awk: 동일한 블록에 있는 if 및 조건문

awk: 동일한 블록에 있는 if 및 조건문

파일 이름이 "pretempsc.cfg"인지 확인하고 해당 내용을 그대로 인쇄해야 하는 스크립트 코드는 다음과 같습니다. . 다른 파일의 경우 "abc 비활성화..."로 시작하는 줄만 "no abc..."로 수정해야 합니다.

    #!/bin/sh
    IN_FILE=$1
    OUT_FILE=$2

    WhatFileIsIt() {
    awk -v filename=$IN_FILE '
    BEGIN {
        scnode = 0;
        if (filename == "pretempsc.cfg") {
            scnode = 1; }
    }
    {
        if (!scnode) {
            /^abc disable/ {
            print "no abc "$4"";
            next;
            }

            print;}
        }
        else {print}
    }
    '
    }

    cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE

이 스크립트를 실행할 때 다음 오류가 발생합니다.

 awk: cmd. line:9:         /^abc disable/ {
 awk: cmd. line:9:                        ^ syntax error
 awk: cmd. line:16:     else {print}
 awk: cmd. line:16:     ^ syntax error

내가 찾은 바로는 액션 블록에서 if 및 조건부 액션을 잘못 사용한 것 같지만 정확히 무엇이 잘못되었는지는 알 수 없습니다.

참고: 쉘 스크립트에서 awk를 사용해야 했고, IN_FILE을 자체적으로 처리하는 WhatFileIsIt과 같은 다른 함수도 많이 있었습니다.

답변1

예, 해당 패턴 일치를 전체 문으로 변경해야 합니다 if.

if (/^abc disable/) {
    print "no abc "$4"";
    next;
}

( /pattern/$0 ~ /pattern/, $0전체 입력 줄을 포함하는 약어입니다.)

print그 이후에 입력된 네 번째 열만 인쇄되므로 just no abcabc disable foo bar doo됩니다 no abc bar. 이것이 당신이 원하는 것인지 잘 모르겠습니다.


이 작업을 수행하는 동안 몇 가지 다른 사항이 떠오릅니다. 너무 명확하거나 스크립트의 나머지 부분과 충돌하는 경우 무시해도 됩니다. (너무 많은 실수를 저지르지 않기를 바랍니다.)

끝에 추가 닫는 중괄호가 있는 것 같고 print가장 깊은 조건의 들여쓰기가 약간 벗어난 것 같아서 조금 다시 작성합니다.

{
    if (!scnode) {
        if (/^abc disable/) {
            print "no abc " $4;
            next;
        }
        print;
    } else {
        print;
    }
}

그러나 여기서부터 특별한 일을 하는 유일한 시간은 둘 다 !scnode참이고 /^abc disable/일치하는 경우이며, 다른 모든 경우에만 print조건을 결합할 수 있습니다 &&(물론 서로 다른 유형의 파일 간의 분리는 더 이상 필요하지 않습니다) . 매우 명확합니다).

{
    if (!scnode && /^abc disable/) {
        print "no abc "$4"";
        next;
    } else {
        print;
    }
}

next실행 시간을 단축시키는 a가 있기 때문에 final은 절 없이 그대로 유지 print될 수 있고 else, 실제로 전체 코드 블록이 하나이기 때문에 if조건문을 메인 레벨에 올려놓고 무조건 기본 인쇄 작업을 수행할 수 있습니다.

!scnode && /^abc disable/ {
    print "no abc "$4"";
    next;
}
1;

(물론 지금은 좀 너무 깔끔해 보일 수도 있습니다.)


또한 쉘 스크립트에서는 고양이를 방해할 필요가 없습니다. 고양이를 잠들게 하고 리디렉션을 위해 쉘을 사용하는 것이 더 좋습니다. (그리고 쉘 변수를 인용하십시오.)

 WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"

함수의 이름은 약간 혼란스럽습니다. 실제로 "무엇"에 대한 질문에 대답하지 않고 파일을 처리합니다. 어쩌면 비슷한 것일까요 ProcessFile?

글쎄, 함수에 대해 말하자면, 함수는 IN_FILE로컬이 아닌 변수를 사용합니다. 서로 다른 두 파일에 대해 함수를 실행해야 하는 경우 혼란스러울 수 있습니다. 쉘 스크립트 자체와 마찬가지로 함수도 매개변수를 사용하여 호출할 수 MyFunction foo있으며 함수 내에 $1포함될 수 있습니다 .foo

그래서 나는 아마도 다음과 같은 일을 할 것입니다

ProcessFile() {
awk < "$1" -v filename="$1" '
[...]

(입력 리디렉션을 awk 명령줄 중간에 배치하든지 끝에 배치하든 상관없습니다.)

다음과 함께 사용:

ProcessFile "$IN_FILE" > "$OUT_FILE"

관련 정보