パターンに従ってファイルを2つの部分に分割

パターンに従ってファイルを2つの部分に分割

大容量ファイルをパターンごとに2つの部分に分割する方法は?

例えばfile.txt:

ABC
EFG
XYZ
HIJ
KNL

このファイルを分割XYZしてfile1XYZfile2

答え1

これは仕事です。csplit:

csplit -sf file -n 1 large_file /XYZ/

sファイルを自動的に分割してプレフィックス付きのセグメントを作成し、同じ単一のf数字filen番号を付けます。file0を使用すると、/regex/一致する行に分割されますが、含まれませんregex。次に分割そしてregexオフセットを追加して一致する線を含めます+1

csplit -sf file -n 1 large_file /XYZ/+1

これにより、2つのファイルが作成されます。 名前を指定する必要がある場合は、いつでもコマンドに空のパターンを追加してfile0最初のファイルを削除できます。file1file1file2csplit

csplit -sf file -n 1 large_file // /XYZ/+1

が作成されましたが空ですfile0ので、安全に削除できます。file1file2file0

rm -f file0

答え2

私達は一緒にawkできます:

awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile


説明する:最初の引数()は、後続の引数()が処理されるときに出力に使用されるawkファイル名で変数を定義します。プログラムは、変数()で指定されたファイルのすべての行を印刷します。パターンが見つかると、出力変数は新しいファイル()を指すようにオーバーライドされ、それは後続のデータ行を印刷するためのターゲットとして使用されます。out=file1largefileawkout{print >out}XYZ{out="file2}"

引用:

答え3

現代では、上記の基本的な答えの1つにkshシェルバリエーションがあります(つまり、なし)。sedsed

{ 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

関連情報