awk /pattern/ { print "text"} /pattern/ {print ""}를 사용할 때 ELSE 모드가 있습니까?

awk /pattern/ { print "text"} /pattern/ {print ""}를 사용할 때 ELSE 모드가 있습니까?

다음과 같은 텍스트 파일이 있다고 가정해 보겠습니다.

R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

awk이 행을 다른 방식으로 처리 하고 싶습니다 .

awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '

또한 남은 모든 줄을 있는 그대로 인쇄하고 싶습니다(이미 처리한 줄을 반복하지 않고). 기본적으로 /ELSE/ { print $0}줄 끝에 하나를 추가 해야 합니다 awk.

그런 게 있나요?

답변1

단순화된 접근 방식awk

awk '/R1/ {print "=>" $0;next} /R2/{print "*" $0;next} 1' text.file

[jaypal:~/Temp] cat text.file 
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

[jaypal:~/Temp] awk '/R1/ { print "=>" $0;next} /R2/{print "*" $0;next}1' text.file
=>R1 12 324 3453 36 457 4 7 8
*R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
[jaypal:~/Temp] 

패턴 {Action} 문의 획기적인 발전:

  • /R1/ { print "=>" $0;next}: /R1/인쇄 작업이 포함된 라인이 실행됨을 나타냅니다. 이는 awk 문의 나머지 부분이 무시되고 다음 줄이 검토된다는 의미입니다.=>next

  • /R2/{print "*" $0;next}: 이는 pattern /R2/인쇄 작업과 일치하는 라인이 실행된다는 의미입니다. 처리가 시작 *되면 의 경우와 마찬가지로 awk첫 번째 pattern {action}문이 무시됩니다 . 이렇게 하면 두 번째 문이 완료됩니다. 이는 더 이상 처리를 원하지 않고 적절하게 다음 줄로 이동한다는 의미입니다.pattern /R1//R2/pattern {action}nextawk

  • 1모든 줄을 인쇄합니다. 조건이 제공되지 않은 경우 {action}awk는 기본적으로 using을 사용합니다 {print}. 여기의 조건은 1true로 해석되므로 항상 성공합니다. 이 지점에 도달하면 첫 번째와 두 번째 문이 무시되거나 무시되기 때문입니다 ( 및 를 pattern {action}포함하지 않는 줄의 경우 ). 따라서 기본 인쇄 작업이 나머지 줄에서 수행됩니다./R1//R2/

답변2

awk조건문에서 일반적인 의심을 구현합니다. 경기에서 달성하고 싶은 것 printf대신에 사용하는 것이 가장 좋습니다 .print

awk '{ if (/^R1/) { printf("=> %s\n", $0) } else if (/^R2/) { printf("* %s\n", $0) } else { print $0 } }'

답변3

Chris Down은 블록 내에서 명시적인 "if" 문을 사용하여 정규식의 else를 얻는 방법을 보여주었습니다. 동일한 효과를 얻을 수 있는 다른 방법도 있지만 그의 솔루션이 더 나을 수도 있습니다.

하나는 일치하지 않는 텍스트에만 일치하는 세 번째 정규식을 작성하는 것입니다. 귀하의 경우에는 다음과 같습니다.

awk '/^R1/ { print "=>" $0}
     /^R2/ { print "*" $0}
     /^[^R]/ || /^R[^12]/ { print $0 } '

이는 고정된 정규식을 사용한다는 점에 유의하세요. 정규식 시작 부분의 ^는 줄의 시작 부분에서만 일치합니다. 원래 패턴은 이 작업을 수행하지 않으며 대신 줄의 모든 문자를 확인하므로 일치 속도가 약간 느려집니다. 다음 줄로 점프하는 거죠. 세 번째("else") 경우는 "R"([^R]) 이외의 문자로 시작하는 줄 또는 "R"로 시작하고 뒤에 "1" 또는 "" 이외의 문자가 오는 줄과 일치합니다. 2'(R[^12]). ^의 두 가지 다른 의미는 약간 혼란스럽습니다. 하지만 이 실수는 오래 전에 발생했으며 조만간 바뀌지 않습니다.

보완적인 정규식을 사용하려면 고정되어야 합니다. 그렇지 않으면 [^R]이 그 뒤에 오는 1과 일치합니다. 이 방법은 귀하와 같이 매우 간단한 정규식에 유용할 수 있지만 정규식이 더욱 복잡해지면 이 방법을 관리하기 어려워집니다. 대신 다음과 같이 각 행에 상태 변수를 사용할 수 있습니다.

awk '{ handled = 0 }
     /^R1/ { print "=>" $0; handled = 1}
     /^R2/ { print "*" $0; handled = 1}
     { if (!handled) print $0 } '

그러면 각 새 줄의 처리가 0으로 설정되고, 두 정규식 중 하나와 일치하면 1로 설정되며, 마지막으로 여전히 0이면 $0를 인쇄합니다.

관련 정보