일치가 성공한 후 awk에서 단일 라인 처리를 중지하시겠습니까?

일치가 성공한 후 awk에서 단일 라인 처리를 중지하시겠습니까?

awk에서 한 줄 처리를 중지하는 방법이 있나요? 액션 내의 제어 구조보다는 패턴-액션 쌍에 대해 작동하는 것과 같은 break것이 있습니까 ?continue

다음 파일이 있고 각 이름을 , , , input.txt로 바꾸려고 한다고 가정 해 보겠습니다 . 하지만 공백으로 시작하거나 단독으로 시작하는 줄을 남기고 싶습니다 .x0x1x2...-

-- data
bob     4
joe     5
bob     6
joe     7

이 되다:

-- data
x0 4
x1 5
x0 6
x1 7

이 작업을 수행하는 다음 스크립트가 있습니다. (그런데, 문자열 리터럴 대신 구분 기호를 사용하여 이를 구성하는 더 좋은 방법이 있을 수 있습니다.)

#!/bin/sh
awk '
    BEGIN { c = 0; }

    # do not process lines beginning with - or space
    /^[- ]/ {
        print;
    }

    # update 
    /^[^- ]/ {
        if (! ($1 in name) ) {
            new_name = "x" c;
            c += 1;
            name[$1] = new_name;
        }
        $1 = name[$1];
        print;
    }
' input.txt

이 스크립트에는 몇 가지 단점이 있습니다. 첫째, 우리는 상호 배타적이라는 사실을 알고 있지만 /^[- ]//^[^- ]/재산은 어디에도 적용되지 않습니다. break첫 번째 일치 후 행 처리를 포기하는 것과 같은 기능을 사용할 수 있기를 바랍니다 .

/^[- ]/ {
    print;
    break;
}

처음 두 패턴 중 어느 것과도 일치하지 않는 비어 있지 않은 행이 있는 경우 문제가 있음을 사용자에게 경고하기 위해 다른 절을 추가할 수 있기를 원합니다.

/./ {
    print "non-empty line!" > "/dev/stderr"
    # or print "non-empty line!" > "/dev/tty" if portability is a concern
}

그러나 이 패턴 작업 쌍을 있는 그대로 스크립트에 추가하면 비어 있지 않은 모든 줄 이후에 실행됩니다.

행이 "성공적으로" 처리되었으므로 해당 행 처리를 중지하기 위해 처음 두 테스트 사례 후에 추가할 수 있는 것이 있습니까? 이것이 가능하지 않은 경우 포괄적인 상황을 처리하기 위한 일반적인 awk 관용구가 있습니까?

답변1

awk명령문을 사용하여 next다음 입력 레코드 처리를 즉시 계속할 수 있습니다.

다음은 스크립트의 대체 구현입니다 awk.

awk '/^[- ]/ { print; next } !($1 in n) { n[$1] = sprintf("x%d", c++) } { $1 = n[$1]; print }' data.in

코드 awk

/^[- ]/    { print; next }
!($1 in n) { n[$1] = sprintf("x%d", c++) }
           { $1 = n[$1]; print }

c카운터에요. 처음부터 제로였습니다.

n새 태그/이름을 보유하는 연관 배열입니다. 인덱싱을 위해 파일의 첫 번째 필드/열의 데이터를 사용합니다.

!($1 in n)첫 번째 필드의 데이터에 아직 새 레이블/이름이 할당되지 않은 경우 참입니다.

관련 정보