발생 횟수를 표시하고 그 사이와 마지막 행 이후의 줄 수를 계산합니다.

발생 횟수를 표시하고 그 사이와 마지막 행 이후의 줄 수를 계산합니다.

나는 이 파일을 가지고 있습니다 :

table_01 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_02 (id, field01, field02, field03)
record_01
table_03 (id, field01, field02, field03, field04)
record_01
record_02
table_04 (id, field01, field02, field03, field04, field04)
record_01
table_05 (id, field01, field02, field03, field04)
record_01
record_02
record_03
record_04

table" "라는 단어가 나타나는 줄을 표시하고 그 사이의 줄 수와 마지막 발생 이후의 줄 수를 표시하는 스크립트를 원합니다 .

따라서 출력은 다음과 같습니다.

table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4

지금까지 다음 스크립트가 있습니다.

awk '$0 ~ /table/ {if (n) print NR-1-n; n=NR}' file

출력은 다음과 같습니다.

3
1
2
1

그러나 스크립트는 table" "가 나타나는 줄을 표시하지 않으며 마지막 발생 이후의 줄도 표시하지 않습니다. 누락된 내용을 표시하려면 어떻게 수정해야 합니까?

답변1

분명히 작업의 90%를 완료했습니다.

awk '/table/ {if (n) 인쇄 NR-1-n; 인쇄}
     END {if (n) 인쇄 NR-1-n}'             문서

$0 ~그럴 필요는 없습니다 .

답변2

나는 Perl 솔루션을 구성했습니다:

perl -Mfeature=say -e '
    while (<>) {
        if (/^table/) {
            $c && say $c;
            print;
            $c = 0;
            next;
        }
        $c++;
    }
    say $c;
' <input
user@server ~/[REDACTED] (git)-[REDACTED] % perl -Mfeature=say -e '
    while (<>) {
        if (/^table/) {
            $c && say $c;
            print;
            $c = 0;
            next;
        }
        $c++;
    }
    say $c;
' <input
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4

답변3

내 대답은 빈 테이블("빈 테이블" 행/일치하는 행)이 있을 수 있는 시나리오와 입력 파일에 추가(테이블이 아닌/일치하지 않는) 행이 추가될 수 있는 일반적인 시나리오를 가정합니다.

이 경우 테이블 행(일치하는 행)을 표시하고 후속 레코드 행(일치하지 않는 행)의 발생 횟수를 계산하려면 awk원하는 경우 다음 패턴을 사용하세요 ^table.

awk '
  /^$/ {next}
  /^table/ {
    if (precedingmatch)
      {print 0}
    else if (n)
      {print n}
    
    print; n=0; precedingmatch=1; matchesfound=1
  }
  !/^table/ {
    if (matchesfound) {n++}
    
    precedingmatch=0
  }
  END {if (matchesfound) {print n} else {print 0} }
' file.txt
  • precedingmatch0다음 두 행이 테이블 행인 경우 인쇄하는 데 사용됩니다.
  • matchesfound첫 번째 테이블 행 앞에 있는 테이블이 아닌 행의 수를 인쇄하는 것을 무시하는 데 사용됩니다.

file.txt일부 "빈 테이블", 개행 및 무작위로 추가된 행을 사용하는 예:

randomline_01
randomline_02
table_01 (id, field01, field02, field03, field04)
table_02 (id, field01, field02, field03)
record_01
record_02

table_03 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_04 (id, field01, field02, field03, field04, field05)
table_05 (id, field01, field02, field03, field04)

산출:

table_01 (id, field01, field02, field03, field04)
0
table_02 (id, field01, field02, field03)
2
table_03 (id, field01, field02, field03, field04)
3
table_04 (id, field01, field02, field03, field04, field05)
0
table_05 (id, field01, field02, field03, field04)
0

"테이블" 줄이 없는 파일, 빈 파일 또는 개행 출력으로 가득 찬 파일 0.

답변4

사용행복하다(이전 Perl_6)

~$ raku -ne 'BEGIN my $c = 0;  if /^table/ { $c && put $c; .put; $c = 0; next}; $c++;'  file

Raku는 유니코드를 고급 지원하는 Perl 제품군의 프로그래밍 언어입니다. 이 Raku 솔루션은 @kos 및 @terdon이 게시한 일반 개요(Perl)를 따릅니다.

입력 예( tableOP에서 이러한 내용이 발생하지 않을 것이라고 말했음에도 불구하고 끝에 추가 줄이 있음):

table_01 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_02 (id, field01, field02, field03)
record_01
table_03 (id, field01, field02, field03, field04)
record_01
record_02
table_04 (id, field01, field02, field03, field04, field04)
record_01
table_05 (id, field01, field02, field03, field04)
record_01
record_02
record_03
record_04
table_06 (id, field01, field02, field03, field04)
table_07 (id, field01, field02, field03, field04)

예제 출력:

table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
table_06 (id, field01, field02, field03, field04)
table_07 (id, field01, field02, field03, field04)

위에 제공된 답변은 @kos 및 @terdon의 Perl 답변과 동일합니다. 더 명확하게 말하면 블록 내의 첫 번째 문은 $c.Bool && put $c;or 로 작성할 수 있지만 $c.so && put $c;위의 코드로 충분합니다.


"비테이블" 레코드가 삽입되지 않으면 0이 삽입됩니다.

0이것은 record헤더 뒤에 줄이 없을 때 반환되는 코드 입니다 table(@Aeronautix의 답변과 유사).

~$ raku -ne 'BEGIN my $c = 0;  if /^table/ { $c && put($c-1); .put; $c = 0}; $c++; END put($c-1);'  file
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
table_06 (id, field01, field02, field03, field04)
0
table_07 (id, field01, field02, field03, field04)
0

참고: 위의 모든 답변에 대해 코드는 첫 번째 줄이 로 시작한다고 가정 table하고 OP는 첫 번째 줄 앞에 잘못된 줄이 없음을 확인합니다 table.

그러나 (다른 사용자/데이터 소스의 경우) record파일 상단에 잘못된 줄이 있으면 첫 번째 대답은 해당 잘못된 줄 앞의 줄 수를 반환합니다.첫 번째테이블라인. 두 번째 대답은 "1 빼기" 이전의 행 수를 반환합니다.첫 번째테이블라인.

https://raku.org

관련 정보