異なるサブディレクトリのファイルを連結するにはどうすればいいですか?

異なるサブディレクトリのファイルを連結するにはどうすればいいですか?

大きなフォルダがあり、その中にはそれぞれ多くの.txtファイルを含むサブディレクトリが多数あります。これらすべてのファイルを 1 つの.txtファイルに連結したいと考えています。 を使用してサブディレクトリごとにこれを行うことはできますcat *.txt>merged.txtが、大きなフォルダ内のすべてのファイルに対してこれを行うことを試みています。どうすればよいでしょうか?

答え1

試してみる

find /path/to/source -type f -name '*.txt' -exec cat {} + >mergedfile

サブディレクトリ内のすべての '*.txt' ファイルfを再帰的に検索し、すべてを 1 つに連結します。/path/to/sourcemergedfile

ディレクトリ内の各サブディレクトリのファイルを連結するには、次のようにします。

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これらを再度追加するには を使用します)。

関連情報