大容量ファイルをパターンごとに2つの部分に分割する方法は?
例えばfile.txt
:
ABC
EFG
XYZ
HIJ
KNL
このファイルを分割XYZ
してfile1
。XYZ
file2
答え1
これは仕事です。csplit
:
csplit -sf file -n 1 large_file /XYZ/
s
ファイルを自動的に分割してプレフィックス付きのセグメントを作成し、同じ単一のf
数字file
でn
番号を付けます。file0
を使用すると、/regex/
一致する行に分割されますが、含まれませんregex
。次に分割そしてregex
オフセットを追加して一致する線を含めます+1
。
csplit -sf file -n 1 large_file /XYZ/+1
これにより、2つのファイルが作成されます。 名前を指定する必要がある場合は、いつでもコマンドに空のパターンを追加してfile0
最初のファイルを削除できます。file1
file1
file2
csplit
csplit -sf file -n 1 large_file // /XYZ/+1
が作成されましたが空ですfile0
ので、安全に削除できます。file1
file2
file0
rm -f file0
答え2
私達は一緒にawk
できます:
awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
説明する:最初の引数()は、後続の引数()が処理されるときに出力に使用されるawk
ファイル名で変数を定義します。プログラムは、変数()で指定されたファイルのすべての行を印刷します。パターンが見つかると、出力変数は新しいファイル()を指すようにオーバーライドされ、それは後続のデータ行を印刷するためのターゲットとして使用されます。out=file1
largefile
awk
out
{print >out}
XYZ
{out="file2}"
引用:
答え3
現代では、上記の基本的な答えの1つにksh
シェルバリエーションがあります(つまり、なし)。sed
sed
{ read in <##XYZ ; print "$in" ; cat >file2 ;} <largefile >file1
別の別のバリエーションがありますksh
(つまり、省略cat
)。
{ read in <##XYZ ; print "$in" ; { read <##"" ;} >file2 ;} <largefile >file1
(純粋なksh
解決策はかなりうまくいくようです。2.4 GBのテストファイルでは19〜21秒かかりますが、/ベースのsed
アプローチcat
は39〜47秒かかります)。
答え4
GNU sedを使ってこれを試してください:
sed -n -e '1,/XYZ/w file1' -e '/XYZ/,${/XYZ/d;w file2' -e '}' large_file