list_of_files.txt
というファイル内にファイル名のリストがあります。
そのリストの各ファイルの内容をall_compounds.sdf
という別のファイルにコピーしたい。
コマンドラインからこれを行うにはどうすればよいですか?
ファイル名を取得するために単純なコマンド置換を使用しないでください(スペースやその他の特殊文字で簡単に壊れる可能性があります)。 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)
周囲の括弧()
はこれをサブシェルで実行し、現在のシェルがこれらの変更の影響を受けないようにします。
早くて汚い方法...
cat $(cat list_of_files.txt) >> all_compounds.sdf
注意:これは、リスト内のファイル名が非常に適切に動作している場合にのみ機能します-スペース、改行、または文字がシェルにとって特別な意味を持ちます-信頼できる結果を得るために 代わりにこの答え を使用してください)
cat
concatenatesファイル。また、コンテンツも印刷します。command2 $(command1)
を使用すると、command1
(cat list...
)の出力をファイルを連結するcommand2
(cat
)に渡すことができます。次に、リダイレクト>>
を使用して、出力をstdoutに出力する代わりにファイルに送信します。出力を表示する場合は、代わりにtee
を使用します。
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(ファイルが既に存在する場合に>>
およびtee
の代わりに>
の代わりに-a
を使用しました-thisappends既に存在する場合、上書きするのではなくファイルに)
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