多数のテキストファイルを1つの大きなテキストファイルにまとめる

多数のテキストファイルを1つの大きなテキストファイルにまとめる

何千もの小さなテキストファイルを1つの大きなテキストファイルに結合したいと考えています。これらのファイルは、次のような構造のディレクトリにあります。timestamp1/status.txtたとえば、20130430133144/status.txt次のようになります。これまでのところ、

cat */* > bigtextfile.txt

少数のファイルには機能します。しかし、より多くのファイルにも機能しますか? はcatすべてのファイルのコンテンツを収集し、 に保存しようとするのでしょうか。bigtextfileそうでない場合は、1 つのファイルを取得して に追加しbigtextfile、別のファイルを取得するなど、別の方法があるはずです。

答え1

で:

cat */* > bigtextfile.txt

シェルは、*/*一致するファイル(非表示ではない)のソートされたリストを展開し、catそれらのファイル パスを引数として実行します。

cat各ファイルを順番に開き、ファイルから読み取った内容を標準出力に書き込みます。catメモリ内には、一度に 1 バッファ分以上のデータ (数キロバイト程度) は保持されません。

ただし、引数リストがcat大きすぎて、システム コールの引数のサイズの制限に達するという問題が発生する場合がありますexecve()。そのため、ファイルのリストを分割して複数回実行する必要がある場合がありますcat

そのために、以下を使用できますxargs(ここでは、xargs非標準-rおよび-0オプションとして GNU または BSD を使用します)。

printf '%s\0' */* | xargs -r0 cat -- > big-file.txt

(printfシェルに組み込まれているため、execveシステム コールを経由せず、その制限も通過しません)。

または、findファイルのリストを作成し、必要な数の cat コマンドを実行します。

find . -mindepth 2 -maxdepth 2 -type f -exec cat {} + > big-file.txt

またはポータブル:

find . -path './*/*' -prune -type f -exec cat {} + > big-file.txt

(ただし、 とは逆に*/*、隠しファイル (および隠しディレクトリ内のファイル) が含まれ、ディレクトリへのシンボリックリンク内のファイルは検索されず、ファイルのリストはソートされないことに注意してください)。

最近のバージョンの Linux では、次のようにして引数のサイズ制限を解除できます。

ulimit -s unlimited
cat -- */* > big-file.txt

ではzsh、 も使用できますzargs:

autoload zargs
zargs -- */* -- cat > big-file.txt

を使用するとksh93、以下を使用できますcommand -x

command -x cat -- */* > big-file.txt

これらはすべて同じことを実行し、ファイルのリストを分割してcat必要な数のコマンドを実行します。

再度、組み込みコマンドを使用して制限をksh93回避することができます。execve()cat

command /opt/ast/bin/cat -- */* > big-file.txt

答え2

「いいえ」catの場合、書き込みを開始する前にすべてのファイルをバッファリングしません。

ただし、多数のファイルがある場合は、 に渡される引数の数に関する問題が発生する可能性がありますcat。デフォルトでは、Linux カーネルは、任意のプログラムに渡される引数の数が固定されているだけです (値の取得方法は覚えていませんが、ほとんどの場合、数千です)。
この問題を解決するには、代わりに次のようにします。

find -mindepth 2 -maxdepth 2 -type f -exec cat {} \; > bigtextfile.txt

catこれは基本的に、 によって見つかった各ファイルごとに個別に呼び出しますfind

答え3

ファイル数が多すぎる場合、*/*引数リストが大きくなりすぎます。その場合は、次のような方法があります。

find . -name "*.txt" | xargs cat > outfile

(アイデアとしては、 を使用しfindてファイル名を取得し、それをストリームにし、 がxargsこのストリームを管理しやすい大きさに切り分けて に渡しcat、 がそれらを の出力ストリームに連結しxargs、それが に入るというものですoutfile)。

関連情報