
大きなフォルダがあり、その中にはそれぞれ多くの.txt
ファイルを含むサブディレクトリが多数あります。これらすべてのファイルを 1 つの.txt
ファイルに連結したいと考えています。 を使用してサブディレクトリごとにこれを行うことはできますcat *.txt>merged.txt
が、大きなフォルダ内のすべてのファイルに対してこれを行うことを試みています。どうすればよいでしょうか?
答え1
試してみる
find /path/to/source -type f -name '*.txt' -exec cat {} + >mergedfile
サブディレクトリ内のすべての '*.txt' ファイルf
を再帰的に検索し、すべてを 1 つに連結します。/path/to/source
mergedfile
ディレクトリ内の各サブディレクトリのファイルを連結するには、次のようにします。
find . -mindepth 1 -type d -execdir sh -c 'cat $1/*.txt >> $1/mergedfile' _ {} \;
答え2
Bash を使用しており、テキスト ファイルの数が制限されている場合 (つまり、最大引数数の制限を超えていない場合。最大引数数は非常に大きいですが、無限ではありません)、次のglobstar
機能を使用してこれを簡単に実現できます。
$ shopt -s globstar
$ cat **/*.txt > merged.txt
より一般的ですが、あまりエレガントではないアプローチは、 をfind
ドライバーとして使用し、cat
各ファイルを呼び出して出力を追加することです。
$ find -name \*.txt -exec sh -c 'cat {} >> merged.out' \;
ここで を呼び出すsh
必要があるのは、それぞれの の結果を追加するためですcat
。出力ファイルが異なる拡張子を持っているか、マージするツリーの外側にあるか、またはfind
出力をそれ自体と連結しようとしていることを確認してください。
答え3
特定の順序で連結する必要がある場合、以下のようにファイルを辞書順 (パス名でソート) で連結しますbash
。
shopt -s globstar
for name in **/*.txt; do
[ -f "$name" ] && cat <"$name"
done >merged.out
find
これはコマンドに似ています
find . -type f -name '*.txt' -exec cat {} ';' >merged.out
順序が異なる可能性があることを除けば、通常のファイルへのシンボリック リンクは含まれ (&& [ ! -L "$name" ]
必要ない場合は を追加)、隠しファイル (および隠しディレクトリ内のファイル) は除外されます (shopt -s dotglob
これらを再度追加するには を使用します)。