将文件分成两部分,以一种模式

d.p*_*tto 15 sed awk text-processing split

如何以一种模式将大文件分成两部分?

举个例子file.txt

ABC
EFG
XYZ
HIJ
KNL
Run Code Online (Sandbox Code Playgroud)

我想这个文件在拆分XYZ,使得file1包含排队到XYZ休息的线条file2

don*_*sti 15

这是一份工作csplit

csplit -sf file -n 1 large_file /XYZ/
Run Code Online (Sandbox Code Playgroud)

silently分割文件,创建与前片ffilen使用一个单一的数字umbered,如file0等。注意,使用/regex/起来会拆分,但不包括行匹配regex。要拆分包含匹配的行,请regex添加+1偏移量:

csplit -sf file -n 1 large_file /XYZ/+1
Run Code Online (Sandbox Code Playgroud)

这将创建两个文件, file0以及file1. 如果您绝对需要命名它们,file1并且file2您始终可以在csplit命令中添加一个空模式并删除第一个文件:

csplit -sf file -n 1 large_file /XYZ/
Run Code Online (Sandbox Code Playgroud)

创建file0file1以及file2但是file0是空的,所以你可以放心地将其删除:

rm -f file0
Run Code Online (Sandbox Code Playgroud)


Jan*_*nis 11

有了awk你可以这样做:

awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
Run Code Online (Sandbox Code Playgroud)


说明:第一个awk参数 ( out=file1) 定义了一个带有文件名的变量,该变量将在largefile处理后续参数 ( ) 时用于输出。该awk程序将打印所有行于由变量指定的文件out{print >out})。如果XYZ找到该模式,将重新定义输出变量以指向新文件 ( {out="file2}"),该文件将用作打印后续数据行的目标。

参考:


mik*_*erv 6

{ sed '/XYZ/q' >file1; cat >file2; } <infile
Run Code Online (Sandbox Code Playgroud)

对于 GNU,sed您应该使用-unbuffered 开关。不过,大多数其他seds 应该可以正常工作。

离开XYZ...

{ sed -n '/XYZ/q;p'; cat >file2; } <infile >file1
Run Code Online (Sandbox Code Playgroud)


Jan*_*nis 6

使用现代ksh这里sed是上述sed基于答案之一的外壳变体(即没有):

{ read in <##XYZ ; print "$in" ; cat >file2 ;} <largefile >file1
Run Code Online (Sandbox Code Playgroud)


而另一种ksh单独的变体(即也省略了cat):

{ read in <##XYZ ; print "$in" ; { read <##"" ;} >file2 ;} <largefile >file1
Run Code Online (Sandbox Code Playgroud)


(纯ksh解决方案似乎非常高效;在 2.4 GB 的测试文件上,它需要 19-21 秒,而基于sed/cat的方法则需要 39-47 秒)。