stdoutを分割して複数の出力ファイルに移動する方法は?


12

たとえば、command大量の行を標準出力に出力するコマンドがあります。

line1
line2
.....
lineN

出力をディスクに保存しますが、単一のファイルとしてではなく、それぞれが1000行のstdoutを持つ一連のファイルとして保存します。

file0001.txt:
-------------
line1
....
line1000

file0002.txt:
-------------
line1001
....
line2000

etc

私は答えをグーグルで検索しようとしましたが、グーグルが私にtee命令するように指示するたびに、これはこの状況では役に立ちません。おそらく、間違ったクエリを入力しています。

回答:


24

ファイルの保存が完了したらsplit、行数に基づいて常にファイルをファイルピースまたは複数のファイルに分割できます。

split -l 1000 output_file

またはさらに良いだけで試してみてください

command | split -l 1000 -

これにより、出力ストリームが1000行ごとにファイルに分割されます(デフォルトは-lオプションなしの1000行です)。

以下のコマンドを使用すると、出力が生成され、ファイルに格納するために分割されるときに生成されるファイル名にプレフィックスを追加または適用する柔軟性が得られます。

command | split -l 1000 - small-


私は混乱したので、他の人split [arguments...] [input e.g. "-" for stdin] [output_prefix]にとっては、たとえば、:tar -c somedir | split --byes 100MB --numeric-suffixes --suffix-length=3 - somedir.tar.part-001、002 somedir.tar.part-000ans という名前の100MBファイルの束を出力します。
ThorSummoner

3

bashスクリプトを使用できます lines.bash

#!/bin/bash
a=0
while IFS='' read -r line
do
  printf -v filename "%04d.txt" "$((a++/1000))"
  echo "$line" >> $filename
done

そしてそれを次のように使用します:

cat long_file.txt | bash lines.bash

私が気づいた唯一の問題は、*サインインに関するものですlong_file.txt(誰かがそれを修正できます)。


2
IFSを空の文字列に設定して、単語の分割を回避しreadます。で-rバックスラッシュのエスケープを無効にするために使用しますread。で-eバックスラッシュがエスケープしないように削除しますecho。での単語の分割を避けるために引用符を使用しechoます。4.0以降で使用-vbashて、サブプロセスの開始を回避します。現在のコードは999行のみを最初のファイルに配置するため、ポストインクリメントを使用します。a=0; while IFS='' read -r line; do printf -v filename "%04d.txt" $((a++/1000)); echo "$line" >> "$filename"; done
マナトワーク

@manatworkありがとうございます。私だけprintf-vスイッチを持っていません。(bash 4.2.10)。少なくともそれはのmanページではありませんprintf
xralf

1
man printf/ usr / bin / printfを文書化しますが、これは決して環境変数を設定することはありません。シェルの組み込みのドキュメントを参照help printfしてくださいprintf
マナトワーク

@manatwork OK。++/一部にはまだ構文エラーがあるようです。
xralf

1
もう1つ:パラメーターの展開を明示的に必要としない限り、算術評価の中でsigilを使用する必要はありません。算術展開では、変数はとにかく評価されます。
マナトワーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.