複数のファイルの内容を結合ファイルに追加しようとしています。今私はこれをしています:
cat file1 >> file2 >> file3 >> combined
うまくいきますが、問題は、ディレクトリ内のすべてのファイルに対してこの動作を動的に複製したいということです。私は次のアプローチを試しました。
for f in *; do
cat "$f" >> combined
done
しかし、期待どおりに動作しないようです。
答え1
そこにあるループは次のとおりです。
for f in *; do cat "$f" >> combined done
ファイルがcombined
あらかじめ存在しない場合は大丈夫なので、 で生成されたリストには含まれません*
(また、ファイル名が で始まらないと仮定します-
)。
存在する場合、ループは最終的に実行され、cat combined >> combined
システムスペースが不足するか、プログラムが中断されるまでファイルの内容を同じファイルに追加します。 GNUバージョンのcatを実行しないとエラーが発生します。"cat:combination: 入力ファイルが出力ファイルです。"。
$f
これを防ぐには、次のように明示的に確認できますcombined
。
for f in *; do
if [ "$f" != combined ]; then
cat < "$f" >> combined
fi
done
combined
または除外された(Bashから)globパターンを使用してください。
shopt -s extglob
for f in !(combined); do
cat < "$f" >> combined
done
cat
この場合、ループを放棄してすべてのファイル名のリストを一度に提供することをお勧めします。
cat ./!(combined) >> combined
(!(combined)
ksh(この構文のソース)でも機能する必要があります。zshでは、その構文はset -o extendedglob; cat ./^combined >> combined
ksh構文より優れており、後でサポートされる予定ですset -o kshglob
。)