bash: 空白のあるファイルの移動

bash: 空白のあるファイルの移動

ファイル名にスペースを含む単一のファイルを移動すると、次のように動作します。

$ 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番目の例はうまくいきません。どのように動作させることができますか?

ベストアンサー1

いつも、いつも使ってくださいfor foo in $(cat bar)。これは一般的に知られているエラーです。バッシュトラップ番号1。以下を使用する必要があります。

while IFS= read -r file; do mv -- "$file" "new_place/$file"; done < file_list.txt

forループを実行すると、bashは読み取る内容にトークン化を適用します。つまり、、、および次a strange blue cloudに読み込まれます。astrangebluecloud

$ 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

それとも頑張るならウルク:

$ cat files | while IFS= read -r file; do echo "$file"; done
a strange blue cloud.txt

したがって、whileループは入力を読み取り、をread使用して各行を変数に割り当てます。IFS=入力フィールド区切り文字をNULL *に設定すると、この-rオプションはreadバックスラッシュエスケープを解釈しないようにします(タブの代わりに\tスラッシュ+として扱われます)。tafterは、「--の後のすべてをオプションではなく引数として扱う」ことを--意味します。これにより、正しいファイル名で始まるファイル名を適切に処理できます。mv-


* 厳密に言えば、ここでは必要ありません。この場合の唯一の利点は、read先行または末尾のスペースを削除しないことです。ただし、改行文字を含むファイル名を処理する必要があるか、通常は任意のファイル名を処理できます。

おすすめ記事