
何千もの小さなテキストファイルを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
)。