在Shell脚本中将大文件拆分成较小的块

时间:2017-01-26 00:29:45

标签: bash shell split csplit

我需要根据使用shell脚本在较大文件中最后一次出现的模式将较大的文件拆分为较小的块。例如。

Sample.txt(文件将根据要搜索的模式的第三个字段进行排序)

NORTH EAST|0004|00001|Fost|Weaather|<br/> 
NORTH EAST|0004|00001|Fost|Weaather|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 
WEST|0002|00112|WERT|fersg|<br/>
SOUTHWEST|3456|01134|GDFSG|EWRER|<br/> 
要搜索的

“模式1 = 00003”输出文件必须包含sample_00003.txt

NORTH EAST|0004|00001|Fost|Weaather|<br/> 
NORTH EAST|0004|00001|Fost|Weaather|<br/>
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 

“Pattren 2 = 00112”要搜索的输出文件必须包含sample_00112.txt

EAST|0007|00016|uytr|kert|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 

使用

awk -F'|' -v 'pattern="00003"' '$3~pattern big_file' > smallfile

和grep命令但由于文件大小超过300 MB,因此非常耗时。

2 个答案:

答案 0 :(得分:2)

不确定你是否会找到比awk更快的工具,但这里有一个变种可以修复你自己的尝试,并且通过使用 string 匹配而不是< em> regex 匹配。

它在循环中处理查找值,并将从上一次迭代中断的所有内容输出到手头值的 last 出现的所有内容到smallfile<n>的文件,其中{{ 1}}是以<n>开头的索引。

1

请注意,虚拟值ndx=0; fromRow=1 for val in '00003' '00112' '|'; do # 2 sample values to match, plus dummy value chunkFile="smallfile$(( ++ndx ))" fromRow=$(awk -F'|' -v fromRow="$fromRow" -v outFile="$chunkFile" -v val="$val" ' NR < fromRow { next } { if ($3 != val) { if (p) { print NR; exit } } else { p=1 } } { print > outFile } ' big_file) done 可确保在匹配的最后一个真值之后的任何剩余行也会保存到块文件中。

请注意,将所有逻辑移动到单个|脚本中的速度要快得多,因为awk只需要读取一次

big_file

答案 1 :(得分:0)

您可以尝试使用Perl:

 perl -ne '/00003/ && print' big_file > small_file

并将其时间与其他解决方案进行比较......

修改

限制我对你没有尝试的工具的答案......你也可以使用:

sed -n '/00003/p' big_file > small_file

但我倾向于认为perl会更快。再次......我建议你自己测量不同解决方案的流逝时间。