大きなファイルをパターンで2つの部分に分割する方法は?
file.txt
の例を示します:
ABC
EFG
XYZ
HIJ
KNL
このファイルをXYZ
で分割して、file1
がXYZ
までの行とfile2
の残りの行を含むようにします。
awk
を使用すると、次のことができます。
awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
説明:最初のawk
引数(out=file1
)は、後続の引数(largefile
)の処理中に出力に使用されるファイル名を持つ変数を定義します。 awk
プログラムは、変数out
({print >out}
)。パターンXYZ
が見つかると、出力変数は新しいファイル({out="file2}"
)は、後続のデータ行を印刷するためのターゲットとして使用されます。
参考文献:
これは csplit
の仕事です:
csplit -sf file -n 1 large_file /XYZ/
s
ilentlyファイルを分割し、pre f
ix file
およびn
umberedで1桁を使用してピースを作成します。 file0
など。/regex/
を使用すると分割されますが、regex
に一致する行は含まれません。 およびに分割するには、regex
に一致する行を含め、+1
オフセットを追加します。
csplit -sf file -n 1 large_file /XYZ/+1
これにより、file0
とfile1
の2つのファイルが作成されます。 file1
およびfile2
という名前を付ける必要がある場合は、常に空のパターンをcsplit
コマンドに追加して、最初のファイルを削除します。
csplit -sf file -n 1 large_file // /XYZ/+1
file0
、file1
、file2
を作成しますが、file0
は空なので、安全に削除できます。
rm -f file0
{ sed '/XYZ/q' >file1; cat >file2; } <infile
GNU sed
では、-u
nbufferedスイッチ。他のほとんどのsed
sは問題なく動作します。
XYZを除外するには...
{ sed -n '/XYZ/q;p'; cat >file2; } <infile >file1
最新のksh
を使用すると、上記のsed
ベースの回答の1つのシェルバリアント(つまり、sed
なし)が表示されます。
{ read in <##XYZ ; print "$in" ; cat >file2 ;} <largefile >file1
そしてksh
だけの別のバリアント(つまり、cat
も省略):
{ read in <##XYZ ; print "$in" ; { read <##"" ;} >file2 ;} <largefile >file1
(純粋なksh
ソリューションは非常にパフォーマンスが高いようです。2.4GBのテストファイルでは、19〜21秒必要でしたが、sed
/cat
ベースのアプローチ)。
GNU sed:
sed -n -e '1,/XYZ/w file1' -e '/XYZ/,${/XYZ/d;w file2' -e '}' large_file
簡単なハックは、ターゲットパターンが一致したかどうかに応じて、STDOUTまたはSTDERRに印刷することです。次に、シェルの リダイレクト演算子 を使用して、それに応じて出力をリダイレクトできます。たとえば、Perlでは、入力ファイルがf
と呼ばれ、2つの出力ファイルがf1
およびf2
:
分割パターンに一致する行を破棄します。
Perl -ne 'if(/XYZ/){$a=1; next} ; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
一致した行を含める:
Perl -ne '$a=1 if /XYZ/; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
または、別のファイルハンドルに出力します。
分割パターンに一致する行を破棄します。
Perl -ne 'BEGIN{open($fh1,">","f1");open($fh2,">","f2");}
if(/XYZ/){$a=1; next}$a==1 ? print $fh1 "$_" : print $fh2 "$_";' f
一致した行を含める:
Perl -ne 'BEGIN{open($fh1,">","f1"); open($fh2,">","f2");}
$a=1 if /XYZ/; $a==1 ? print $fh1 "$_" : print $fh2 "$_";' f