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分割文件,创建与前片f九file和n使用一个单一的数字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)
创建file0,file1以及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}"),该文件将用作打印后续数据行的目标。
参考:
{ 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)
使用现代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 秒)。