AWK拆分模式错误:空行在行中间拆分

时间:2020-07-21 10:52:02

标签: regex linux bash awk split

我正在尝试通过固定的空行数将大文本文件(10Gb +)分割,并用一个衬线建议here

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

它可以99.99%的时间完成工作,这意味着将文件按nParMax个空行数进行拆分。

但是,一次一次,我在行的中间将最后一段分割为中间(2-3-5行,而不是完整的10-15行)。

我真的很想知道为什么会发生这种错误(正则表达式模式错误?)以及如何避免这种情况的建议。

谢谢!

修改

行为异常的段落:

# sent_id = 170247_3
# text = В то же время видеокадры с места событий свидетельствуют о том, что после звука, похожего на выстрел, находившихся на площади людей охватила паника.
1       В       _       ADP     _       _       4       case    _       O
2       то      _       DET     _       Animacy=Inan|Case=Acc|Gender=Neut|Number=Sing   4       det     _       O
3       же      _       PART    _       _       2       advmod  _       O
4       время   _       NOUN    _       Animacy=Inan|Case=Acc|Gender=Neut|Number=Sing   9       obl     _       O
5       видеокадры      _       NOUN    _       Animacy=Inan|Case=Nom|Gender=Masc|Number=Plur   9       nsubj   _       O
6       с       _       ADP     _       _       7       case    _       O
7       места   _       NOUN    _       Animacy=Inan|Case=Gen|Gender=Neut|Number=Sing   5       nmod    _       O
8       событий _       NOUN    _       Animacy=Inan|Case=Gen|Gender=Neut|Number=Plur   7       nmod    _       O
9       свидетельствуют _       VERB    _       Aspect=Imp|Mood=Ind|Number=Plur|Person=3|Tense=Pres|VerbForm=Fin|Voice=Act      0       root    _       O
10      о       _       ADP     _       _       11      case    _       O
11      том     _       PRON    _       Animacy=Inan|Case=Loc|Gender=Neut|Number=Sing   9       obl     _       O
12      ,       _       PUNCT   _       _       25      punct   _       O
13      что     _       SCONJ   _       _       25      mark    _       O
14      после   _       ADP     _       _       15      case    _       O
15      звука   _       NOUN    _       Animacy=Inan|Case=Gen|Gender=Masc|Number=Sing   25      obl     _       O
16      ,       _       PUNCT   _       _       17      punct   _       O
17      похожего        _       ADJ     _       Case=Gen|Degree=Pos|Gender=Masc|Number=Sing     15      amod    _       O
18      на      _       ADP     _       _       19      case    _       O
19      выстрел _       NOUN    _       Animacy=Inan|Case=Acc|Gender=Masc|Number=Sing   17      obl     _       O
20      ,       _       PUNCT   _       _       15      punct   _       O
21      находившихся    _       VERB    _       Animacy=Anim|Aspect=Imp|Case=Acc|Number=Plur|Tense=Past|VerbForm=Part|Voice=Act 24      acl     _       O
22      на      _       ADP     _       _       23      case    _       O
23      площади _       NOUN    _       Animacy=Inan|Case=Loc|Gender=Fem|Number=Sing    21      obl     _       O
24      людей   _       NOUN    _       Animacy=Anim|Case=Acc|Gender=Masc|Number=Plur   25      obj     _       O
25      охватила        _       VERB    _       Aspect=Perf|Gender=Fem|Mood=Ind|Number=Sing|Tense=Past|VerbForm=Fin|Voice=Act   11      acl     _       O
26      паника  _       NOUN    _       Animacy=Inan|Case=Nom|Gender=Fem|Number=Sing    25      nsubj   _       O
27      .       _       PUNCT   _       _       9       punct   _       O

结果拆分:

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

下一个拆分的文件按照预期的那样干净地启动。半段丢失在某个地方。

编辑2

VIM中的相同段落(# sent_id = 170247_3$)上带有特殊字符(:set list)。拆分发生在第3行(见上文):

# 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$

1 个答案:

答案 0 :(得分:1)

我不确定这是否是您要尝试执行的操作,而是将X段落的文件拆分为n个(以下为{10)文件,其中X是大于或等于n的某个数字。正如我认为您要尝试的那样:

awk -v RS= -v ORS='\n\n' -n 10 '
    NR==FNR { totParas=NR; parasPerFile=2; next }
    (FNR % parasPerFile) == 1 {
        close(out)
        out = FILENAME "_out" (++c)
        parasLeft = totParas - (FNR - 1)
        parasPerFile = int(parasLeft/n) + (parasLeft%n ? 1 : 0)
    }
    { print > out }
' file file