ファイル名にスペースを含む単一のファイルを移動すると、次のように機能します。
$ mv "file with spaces.txt" "new_place/file with spaces.txt"
スペースが含まれている可能性のあるファイルのリストがあり、それらを移動したいと思います。例えば:
$ echo "file with spaces.txt" > file_list.txt
$ for file in $(cat file_list.txt); do mv "$file" "new_place/$file"; done;
mv: cannot stat 'file': No such file or directory
mv: cannot stat 'with': No such file or directory
mv: cannot stat 'spaces.txt': No such file or directory
なぜ最初の例は機能しますが、2番目の例は機能しませんか?どうすれば機能させることができますか?
決してfor foo in $(cat bar)
を使用しないでください。これは、一般的に bash pitfall number 1 として知られている古典的な間違いです。代わりに使用する必要があります:
while IFS= read -r file; do mv -- "$file" "new_place/$file"; done < file_list.txt
for
ループを実行すると、bashは読み取ったものに単語分割を適用します。つまり、a strange blue cloud
はa
、strange
、blue
およびcloud
:
$ cat files
a strange blue cloud.txt
$ for file in $(cat files); do echo "$file"; done
a
strange
blue
cloud.txt
と比較:
$ while IFS= read -r file; do echo "$file"; done < files
a strange blue cloud.txt
または、 oC を要求した場合でも、
$ cat files | while IFS= read -r file; do echo "$file"; done
a strange blue cloud.txt
したがって、while
ループはその入力を読み取り、read
を使用して各行を変数に割り当てます。 IFS=
は、入力フィールド区切り文字をNULLに設定します*、およびread
の-r
オプションは、バックスラッシュエスケープの解釈を停止します(そのため、\t
は、タブではなくスラッシュ+ t
として扱われます)。 mv
の後の--
は、「-以降はすべて引数ではなくオプションとして扱う」ことを意味します。これにより、-
で始まるファイル名を正しく処理できます。
*これはここでは必要ありません。厳密に言えば、このシナリオでの唯一の利点は、先頭または末尾の空白をread
が削除しないことですが、ファイル名を処理する必要がある場合に備えておくとよいでしょう。改行文字を含む、または一般に、任意のファイル名を処理できるようにする必要がある場合。
リストコンテキストのbash
のようなPOSIXシェルの$(cat file_list.txt)
は、split + glob演算子です(zsh
はsplit部分のみを実行しますあなたが期待するように)。
$IFS
(デフォルトでは[〜#〜] spc [〜#〜]、TABおよびNL)の文字で分割し、グロビングを完全にオフにしない限り、グロブ。
ここでは、改行のみで分割し、グロブ部分は不要なので、次のようにする必要があります。
IFS='
' # split on newline only
set -o noglob # disable globbing
for file in $(cat file_list.txt); do # split+glob
mv -- "$file" "new_place/$file"
done
これには、(while read
ループよりも)空の行を破棄し、末尾の終了していない行を保持し、mv
の標準入力(プロンプトの場合などに必要)を保持するという利点もあります。
ただし、ファイルのコンテンツ全体をメモリに保存する必要があるという欠点もあります(bash
やzsh
などのシェルでは数回)。
一部のシェル(ksh
、zsh
、およびより少ない範囲でbash
)では、$(<file_list.txt)
ではなく$(cat file_list.txt)
を使用して最適化できます。
while read
ループで同等のことを行うには、次のものが必要です。
while IFS= read <&3 -r file || [ -n "$file" ]; do
{
[ -n "$file" ] || mv -- "$file" "new_place/$file"
} 3<&-
done 3< file_list.txt
またはbash
を使用:
readarray -t files < file_list.txt &&
for file in "${files[@]}"
[ -n "$file" ] || mv -- "$file" "new_place/$file"
done
またはzsh
を使用:
for file in ${(f)"$(<file_list.txt)"}
mv -- "$file" "new_place/$file"
done
またはGNU mv
and zsh
:
mv -t -- new_place ${(f)"$(<file_list.txt)"}
またはGNU mv
およびGNU xargs
およびksh/zsh/bash:
xargs -rd '\n' -a <(grep . file_list.txt) mv -t -- new_place
bash/POSIXシェルで変数を引用するのを忘れることのセキュリティ上の意味 で展開を引用符で囲まないままにすることの意味の詳細
スクリプトを記述する代わりに、find ..を使用できます。
find -type f -iname \*.txt -print0 | xargs -IF -0 mv F /folder/to/destination/
ファイルがfileにある場合は、次の操作を実行できます。
cat file_with_spaces.txt | xargs -IF -0 mv F /folder/to/destination
二番目はわかりませんが….
幸運を
FIRST INSTALL
apt-get install chromium-browser
apt-get install omxplayer
apt-get install terminator
apt-get install nano (if not already installed)
apt-get install zenity (if not already installed)
THEN CREATE A BASH SCRIPT OF ALL OF THESE PERSONALLY WRITTEN SCRIPTS.
MAKE SURE THAT EVERY Shell SCRIPT IS A .sh FILE ENDING EACH ONE OF THESE IS SCRIPTED TO OPEN UP A DIRECTORY FOR YOU TO FIND AND PICK WHAT YOU WANT.
IT RUNS A BACKGROUND TERMINAL & ALLOWS YOU TO CONTROL THE SONG OR MOVIE.
MOVIE KEYS ARE AS FOLLOWS; p or space bar for pause, q for quit, - & + for sound up and down, left arrow and right arrow for skipping forward and back.
MUSIC PLAYER REALLY ONLY HAS A SKIP SONG AND THAT IS CTRL+C AND IF THAT IS THE LAST SONG OR ONLY SONG THEN IT SHUTS DOWN AND THE TERMINAL GOES AWAY.
****INSTRUCTIONS TO MAKE THE SCRIPTS****
- OPEN UP A TERMINAL
- CD TO THE DIRECTORY YOU WANT THE SCRIPTS TO BE
cd /home/pi/Desktop/
- OPEN UP THE NANO EDITOR WITH THE TITLE OF Shell YOU WANT
Sudo nano Movie_Player.sh
- INSIDE NANO, TYPE OR COPY/PAST (REMEMBER THAT IN TERMINAL YOU NEED TO CTRL+SHIFT+V) THE SCRITP
- SAVE THE DATA WITH CTRL+O
ctrl+o
- HIT ENTER TO SAVE AS THAT FILE NAME OR DELETE THE FILE NAME THEN TYPE NEW ONE JUST MAKE SURE IT ENDS IN .sh THEN HIT ENTER
- NEXT YOU NEED TO Sudo CHMOD IT WITH +X TO MAKE IT CLICKABLE AS A BASH
Sudo chmod +x Movie_Player.sh
- FINALLY RUN IT TO TEST EITHER BY DOUBLE CLICKING IT AND CHOOSING "EXECUTE IN TERMINAL" OR BY ./ IT IN TERMINAL
./Movie_Player.sh
YOU ARE NOW GOOD TO PICK A MOVIE OR SELECT A SONG OR ALBUM AND ENJOY!
**** ALL OF THESE SCRIPTS ACCOUNT FOR SPACES IN THE FILENAME
SO YOU CAN ACCESS "TOM PETTY" OR "SIXTEEN STONE" WITHOUT NEEDING THE " _ " BETWEEN THE WORDS.
-------WATCH A MOVIE SCRIPT ------- (
#!/ bin/bash
FILE = zenity --title "Pick a Movie" --file-selection
「$ {FILE [0]}」のFILE
omxplayer "$ {FILE [0]}"を実行しました
--------LISTEN TO A SONG -------
FILE = zenity --title "Pick a Song" --file-selection
「$ {FILE [0]}」のFILE
「$ {FILE [0]}」を再生します
--------LISTEN TO AN ALBUM ---------- SONGS IN ORDER
DIR = zenity --title "Pick a Album" --file-selection --directory
「$ {DIR [0]}」のDIR
cd "$ {DIR [0]}" && findを実行します。 -type f -name '。ogg' -o -name '。mp3' | sort --version-sort | DIRの読み取り中。 「$ DIR」を再生します
--------LISTEN TO AN ALBUM WITH SONGS IN RANDOM ORDER --------
DIR = zenity --title "Pick a Album" --file-selection --directory
「$ {DIR [0]}」のDIR
cd "$ {DIR [0]}" && findを実行します。 -type f -name '。ogg' -o -name '。mp3' | DIRの読み取り中。 「$ DIR」を再生します