如果平面文件中的标题和内容低于特定行数,则将其删除

如果平面文件中的标题和内容低于特定行数,则将其删除

我有一个包含大约 1000 万行的平面文件:

    query
    ID1
    content1
    content2
    query
    ID2
    content3
    content4
    ...
    content21
    query
    ID3
    content22
    content23
    ...
    content81

文件中少于 10 行的任何块都应删除。例如,第一个块包含 4 行(查询到 content2),应将其删除。此步骤需要在将块拆分为单独的文件之前完成。有什么建议吗?

答案1

可以用 awk 完成:

awk '
# define a long block
BEGIN{
  long = 10;
}
# output long block when new block is found
($1 == "query" && n >= long){
  print s;
}
# new block
($1 == "query"){
  s = "";
  n = 0;
}
# all lines
{
  s = (s != "") ? s "\n" $0 : $0;
  n++;
}
# output the long block if it is the last one in the file
END{
  if (n >= long){
    print s;
  }
}
' input.file > output.file

答案2

sed -e:q -e'$!N;s/\n/&/9;tS' -e'$!bq'     -e:S    \
         -e's|^query.*\n\(query\)|\1|;tq' -e'/\n/{P;D;}'

sed这将始终将当前输入文件的 10 行保留在的缓冲区中。对于每个常规输入行,sedP打印其第一个缓冲区行,然后D将其删除。在Next 周期的顶部,sed将使用 ext 输入线补充其缓冲区N

如果任何点query.*\nquery在其 10 行窗口内匹配,sed将删除除尾随query匹配之外的所有匹配。在下一个周期的顶部,sed将收集输入,直到它补充完滑动窗口缓冲区的所有十行,然后再尝试再次测试输入。

这是一个简单的演示:

for i in      3 6 9 12 15 18                                      
do         
      printf "%s %s %s %s%0${i}s" query ID1 content1 content2
done| tr \  \\n| nl -ba -w1 |
sed -e:q -e'$!N;s/\n/&/9;tS' -e'$!bq'   -e:S    \
         -e's|^[0-9]*.query.*\n\([0-9]*.query\)|\1|;tq' \
         -e'/\n/{P;D;}'

我稍微修改了正则表达式nl以适应输出:

16  query
17  ID1
18  content1
19  content2
20  
21  
22  
23  
24  
25  
26  
27  
28  query
29  ID1
30  content1
31  content2
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  query
44  ID1
45  content1
46  content2
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  query
62  ID1
63  content1
64  content2
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  

sed切掉完全适合其输入窗口的所有序列。它不会错过任何内容,并且一次不需要缓冲超过十行。如果我们l在脚本中添加一个 ook,sed我们可以看到它的缓冲区是什么样子的:

for i in      3 6 9 12 15 18                                      
do         
      printf "%s %s %s %s%0${i}s" query ID1 content1 content2
done| tr \  \\n| nl -ba -w1 |
sed -ne:q -e'$!N;l;s/\n/&/9;tS' -e'$!bq'   -e:S    \
          -e's|^[0-9]*.query.*\n\([0-9]*.query\)|\1|;tq' \
          -e'/\n/{P;D;}'

1\tquery\n2\tID1$
1\tquery\n2\tID1\n3\tcontent1$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\
1$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\
1\n9\tcontent1$
1\tquery\n2\tID1\n3\tcontent1\n4\tcontent2\n5\t\n6\t\n7\tquery\n8\tID\
1\n9\tcontent1\n10\tcontent2$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t\n\
15\t$
7\tquery\n8\tID1\n9\tcontent1\n10\tcontent2\n11\t\n12\t\n13\t\n14\t\n\
15\t\n16\tquery$
16\tquery\n17\tID1$
16\tquery\n17\tID1\n18\tcontent1$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t\n23\
\t$
16\tquery\n17\tID1\n18\tcontent1\n19\tcontent2\n20\t\n21\t\n22\t\n23\
\t\n24\t$

相关内容