これは質問に基づいたものです。ここ。
質問:
- フォルダーにコピーするファイル名をリストした .txt ファイルがあります。新しいフォルダシェル(Macターミナル)から。
方法、どこファイルリスト.txtコピーしたいファイル名が含まれています(\ nで区切られています)。
# version 1
for file in $(cat filelist.txt); do cp "$file" newfolder; done
間違い:
ファイル名があればファイルリスト.txtダッシュ、スペースなどの名前は区別され、No such file
エラーが正しく発生します。
問題を解決しようとした方法は次のとおりです(変数にdbl引用符を追加)。
# version 2
for file in "$(cat filelist.txt)"; do cp "$file" newfolder; done
ただし、これはスペースを区別せずにすべてのファイル名を印刷し、何もコピーしません。
質問:
echo
上記のように引用符を追加すると、名前分割の問題が解決されます。例えばcp
;cat
とを使ってこれを行う正しい方法は何ですかcp
?上記の回答のコメントは、次のことを示しています。set -f;IFS=$'\n'
問題は解決しましたが、それが何であるかわかりません。
どんなアドバイスもありがとうございました!
答え1
ここにはいくつかのオプションがあります。
cat filelist.txt | while read file; do
cp "$file" newfolder
done
それならまずなぜ
for file in $(cat filelist.txt); do cp "$file" newfolder; done
いいえ?ファイルリストに次のものが含まれているとします。
a
b c
$(cat filelist.txt)
ファイル名のリストを生成します。 forループの出力は、次のcat
ように報告解釈されます。
for file in a b c ; do
これは明らかに意図ではありません。
入力フィールド区切り記号に関する注意事項が役立つ部分です。通常、IFS は空白なので、ファイル名のスペースはファイル名間の区切り文字として解釈されます。 IFS が明示的に改行に設定されている場合、スペースは区切り文字と見なされなくなります。
for file in "$(cat filelist.txt)"; do cp "$file" newfolder; done
forループの単一パラメータを作成します。結果は次のとおりです。
for file in "a b c" ; do
したがって、ループは一度だけ実行され、ファイル名は存在しません。