入力リストに基づいてファイルをコピーし、ファイル名に特殊文字を含める

入力リストに基づいてファイルをコピーし、ファイル名に特殊文字を含める

これは質問に基づいたものです。ここ

質問:

  • フォルダーにコピーするファイル名をリストした .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

したがって、ループは一度だけ実行され、ファイル名は存在しません。

関連情報