【问题标题】:Awk fails to split a big file (10Gb+)awk 无法拆分大文件 (10Gb+)
【发布时间】:2020-11-12 03:15:25
【问题描述】:

我正在尝试使用以下脚本在预先指定的空行数上拆分一个大 (10Gb+) 文本文件:

awk 'BEGIN {nParMax = 100000; npar = 0 ;nFile =0}
     /^$/{npar++;if(npar==nParMax){nFile++;npar=0;next}}
     {print $0 > "split_"nFile".out"}'  fname

脚本在 1Gb 以下的文件上运行正常,但是当我在更大的文件上运行它时,文件的末尾被绝对分割在一个随机位置(“随机”意味着我不明白为什么它会在这个位置分割位置。它可能是(i)第一个字段的结尾,或者(ii)字段的中间,或者(iii)注释行的中间。但是,如果我重复拆分实验,awk 总是在据我所知,同一地点)。

“随机”拆分段落的其余部分丢失。新拆分总是从拆分后的行(空行)开始干净。

打开特殊字符的最后一段示例:

# sent_id = 170247_3$
# text = В то же время видеокадры с места событий свидетельствуют о том, что после звука, похожего на выстрел, находившихся на площади людей охватила паника.$
1^IВ^I_^IADP^I_^I_^I4^Icase^I_^IO$
2^Iто^I_^IDET^I_^IAnimacy=Inan|Case=Acc|Gender=Neut|Number=Sing^I4^Idet^I_^IO$
3^Iже^I_^IPART^I_^I_^I2^Iadvmod^I_^IO$
4^Iвремя^I_^INOUN^I_^IAnimacy=Inan|Case=Acc|Gender=Neut|Number=Sing^I9^Iobl^I_^IO$
5^Iвидеокадры^I_^INOUN^I_^IAnimacy=Inan|Case=Nom|Gender=Masc|Number=Plur^I9^Insubj^I_^IO$
6^Iс^I_^IADP^I_^I_^I7^Icase^I_^IO$
7^Iместа^I_^INOUN^I_^IAnimacy=Inan|Case=Gen|Gender=Neut|Number=Sing^I5^Inmod^I_^IO$
8^Iсобытий^I_^INOUN^I_^IAnimacy=Inan|Case=Gen|Gender=Neut|Number=Plur^I7^Inmod^I_^IO$
9^Iсвидетельствуют^I_^IVERB^I_^IAspect=Imp|Mood=Ind|Number=Plur|Person=3|Tense=Pres|VerbForm=Fin|Voice=Act^I0^Iroot^I_^IO$
10^Iо^I_^IADP^I_^I_^I11^Icase^I_^IO$
11^Iтом^I_^IPRON^I_^IAnimacy=Inan|Case=Loc|Gender=Neut|Number=Sing^I9^Iobl^I_^IO$
12^I,^I_^IPUNCT^I_^I_^I25^Ipunct^I_^IO$
13^Iчто^I_^ISCONJ^I_^I_^I25^Imark^I_^IO$
14^Iпосле^I_^IADP^I_^I_^I15^Icase^I_^IO$
15^Iзвука^I_^INOUN^I_^IAnimacy=Inan|Case=Gen|Gender=Masc|Number=Sing^I25^Iobl^I_^IO$
16^I,^I_^IPUNCT^I_^I_^I17^Ipunct^I_^IO$
17^Iпохожего^I_^IADJ^I_^ICase=Gen|Degree=Pos|Gender=Masc|Number=Sing^I15^Iamod^I_^IO$
18^Iна^I_^IADP^I_^I_^I19^Icase^I_^IO$
19^Iвыстрел^I_^INOUN^I_^IAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing^I17^Iobl^I_^IO$
20^I,^I_^IPUNCT^I_^I_^I15^Ipunct^I_^IO$
21^Iнаходившихся^I_^IVERB^I_^IAnimacy=Anim|Aspect=Imp|Case=Acc|Number=Plur|Tense=Past|VerbForm=Part|Voice=Act^I24^Iacl^I_^IO$
22^Iна^I_^IADP^I_^I_^I23^Icase^I_^IO$

生成的拆分位于第 3 行(这是第一个拆分的尾部):

# sent_id = 170247_3
# text = В то же время видеокадры с места событий свидетельствуют о том, что после звука, похожего на выстрел, находившихся на площади людей охватила паника.
1       В       _       ADP     _       _       4       case    _       O
2       то      _       DET     _       Animacy=Inan|Case=Acc|Gender=Neut|Number=Sing   4       det     _       O
3

如果我将文件拆分为 1Gb 以下,问题就会消失。

拆分是在具有 128 GB RAM 的 Ubuntu 服务器上完成的,通过 SSH 在 bash 中使用 GNU Awk 4.1.4,以防万一。

有什么办法可以绕过这个问题?

【问题讨论】:

标签: regex ubuntu unix awk ssh


【解决方案1】:

如果您的代码在 1Gb 文件上运行良好,您可以尝试使用 split 命令将输入​​文件拆分为较小的文件,然后在分段文件上运行您的 awk 代码。

将文件拆分为每个 500 行的文件:

split -l 500 myfile segment

输出文件将是segmentaa、segmentab、segmentac ...

将文件拆分为每个大小为 1Gb 的文件:

split -b 1G myfile segment

输出文件将是 10 个文件名,segmentaa、segmentab、segmentac ...

【讨论】:

  • 如何在随机行上拆分可以代替在空白行上拆分结构良好的文本文件?
  • @EdMorton 这与在错误的地方使用 awk 进行拆分没有什么不同。可能有数千个拆分,应该检查拆分是否正确,打乱,再次组合,按 80/20 拆分,最后解析。
猜你喜欢
  • 1970-01-01
  • 2016-03-12
  • 2022-11-24
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
相关资源
最近更新 更多