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

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

何千もの小さなテキストファイルを1つの大きなテキストファイルにマージしたいです。私はそれらを次の構造のディレクトリに入れましたtimestamp1/status.txt:たとえば: 20130430133144/status.txt。これまで私は知っています

cat */* > bigtextfile.txt

少数のファイルに適しています。しかし、より高い数字でも動作しますか?catすべてのファイルの内容を収集してから保存しようとしているかどうか疑問に思います。そうでない場合は、ファイルをインポートして追加し、別のファイルをインポートするbigtextfileなどの他の方法が必要です。bigtextfileなどのたとえ話。

答え1

存在する:

cat */* > bigtextfile.txt

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

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

ただし、発生する可能性のある問題の1つは、パラメータのリストが大きすぎてcatシステムコールのexecve()パラメータサイズ制限に達することです。したがって、ファイルのリストを分割してcat複数回実行する必要があるかもしれません。

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

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

Pass 以下を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

関連情報