플랫 파일이 특정 줄 수 미만인 경우 헤더와 콘텐츠를 제거합니다.

플랫 파일이 특정 줄 수 미만인 경우 헤더와 콘텐츠를 제거합니다.

약 천만 줄의 플랫 파일이 있습니다.

    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줄이 항상 버퍼에 유지됩니다. 각 일반 입력 라인에 대해 첫 번째 버퍼 라인이 인쇄된 후 삭제 sed됩니다 . 확장 사이클의 상단 에서 해당 버퍼는 확장 입력 라인으로 채워집니다 .PDNsedN

query.*\nquery10줄 창 내에서 일치하는 점이 있으면 후행 일치 항목을 제외한 모든 항목이 sed제거됩니다 . query다음 주기의 맨 위에서 sed입력을 다시 테스트하기 전에 슬라이딩 창 버퍼의 10개 행을 모두 보충할 때까지 입력이 수집됩니다.

다음은 간단한 데모입니다:

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입력 창에 정확히 맞는 모든 시퀀스를 잘라냅니다. 아무것도 놓치지 않으며 한 번에 10줄 이상을 버퍼링할 필요도 없습니다. 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$

관련 정보