다음과 같은 텍스트 파일이 있다고 가정해 보겠습니다.
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}
next
awk
1
모든 줄을 인쇄합니다. 조건이 제공되지 않은 경우{action}
awk는 기본적으로 using을 사용합니다{print}
. 여기의 조건은1
true로 해석되므로 항상 성공합니다. 이 지점에 도달하면 첫 번째와 두 번째 문이 무시되거나 무시되기 때문입니다 ( 및 를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를 인쇄합니다.