web-dev-qa-db-ja.com

リスト内のすべてのファイルの内容を別のファイルにコピーするにはどうすればよいですか?

list_of_files.txtというファイル内にファイル名のリストがあります。

そのリストの各ファイルの内容をall_compounds.sdfという別のファイルにコピーしたい。

コマンドラインからこれを行うにはどうすればよいですか?

15
Ramita Rajaa

ファイル名を取得するために単純なコマンド置換を使用しないでください(スペースやその他の特殊文字で簡単に壊れる可能性があります)。 xargsのようなものを使用します。

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

またはwhile readループ:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

コマンド置換を安全に使用するには、少なくともIFSを改行のみに設定し、グロビング(ワイルドカード展開)を無効にします。

(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

周囲の括弧()はこれをサブシェルで実行し、現在のシェルがこれらの変更の影響を受けないようにします。

20
muru

早くて汚い方法...

cat $(cat list_of_files.txt) >> all_compounds.sdf

注意:これは、リスト内のファイル名が非常に適切に動作している場合にのみ機能します-スペース、改行、または文字がシェルにとって特別な意味を持ちます-信頼できる結果を得るために 代わりにこの答え を使用してください)

ノート

  • cat concatenatesファイル。また、コンテンツも印刷します。
  • コマンド置換command2 $(command1)を使用すると、command1cat list...)の出力をファイルを連結するcommand2cat)に渡すことができます。
  • 次に、リダイレクト>>を使用して、出力をstdoutに出力する代わりにファイルに送信します。出力を表示する場合は、代わりにteeを使用します。

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
    

(ファイルが既に存在する場合に>>およびteeの代わりに>の代わりに-aを使用しました-thisappends既に存在する場合、上書きするのではなくファイルに)

14
Zanna

GNU awkはテキスト処理ユーティリティですが、system()呼び出しを介して外部シェルコマンドを実行できます。私たちはそれを次のように有利に活用できます:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

ここでの考え方は簡単です。ファイルを1行ずつ読み取り、各行から書式付き文字列cat "File name.txt"を作成し、_system()に渡します。

そして、ここで動作しています:

$ ls
file1.txt  file2.txt  file3 with space.txt  file_list.txt


$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3

そのため、タスクの大部分は既に完了しています。リスト上のすべてのファイルを印刷しました。残りは簡単です。>演算子を使用して最終出力をファイルにリダイレクトし、要約ファイルに入れます。

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
4