설명하다:

설명하다:

다음과 같은 파일이 있습니다 swap.

$ cat swap
aardvark BILL CLINTON dog
eternal CLINTON BILL forever
BILL good housekeeping BILL

BILLto 의 모든 항목을 변경하고 to CLINTON 의 모든 항목을 동시에 변경하고 싶습니다 . 결과 출력은 다음과 같습니다.CLINTONBILL

aardvark CLINTON BILL dog
eternal BILL CLINTON forever
CLINTON good housekeeping CLINTON

나는 고전적인 해결책을 알고 있습니다.

sed -e 's/BILL/temp/g' -e 's/CLINTON/BILL/g' -e 's/temp/CLINTON/g'

그러나 누군가가 나에게 연습 차원에서 세 번째 단어를 사용하지 말라고 도전했습니다.

다음 명령을 사용하고 있지만 첫 번째 줄에서만 작동합니다.

$ sed 's/\(BILL\) \(CLINTON\)/\2 \1/g' swap
aardvark CLINTON BILL dog
eternal CLINTON BILL forever
BILL good housekeeping BILL

참고: 저는 Solaris 10 운영 체제를 사용하고 있습니다.

이 인위적인 제약을 관찰하면서 어떻게 원하는 출력을 얻을 수 있습니까?

행동

MORBILLIFORM OVERBILLED
TOM, BILL, AND HARRISON

명시되지 않은.

답변1

perl -pe 's/(BILL)|CLINTON/$1 ? "CLINTON" : "BILL"/eg' swap

설명하다:

-p옵션을 사용하면 Perl파일 la가 awk한 줄씩 읽혀지고 모든 변환이 적용된 후 현재 레코드가 자동으로 인쇄됩니다.

s///명령은 현재 줄에서 작동합니다. 패턴 /eg수정자는 다음과 같습니다. /g변환을 첫 번째 줄로 제한하는 대신 현재 줄에 전역적으로 변환을 적용합니다( 언급하지 않은 경우 .) 는 변환을 코드 로 처리 하는 /g-uate /e수정자 입니다. 평가 후 결과 값은 RHS로 간주됩니다.evalRHSs///Perl

따라서 s/(BILL)|CLINTON/.../은 왼쪽부터 스캔하여 현재 레코드에서 BILL 또는 CLINTON을 찾습니다. BILL이 발견되면 $1이 설정되므로 Perl 표현식 $1 ? "CLINTON" : "BILL"은 현재 레코드에서 BILL이 대체되는 CLINTON으로 평가됩니다. 하지만 수정자 덕분에 우리는 끝났습니다 /g. 마찬가지로, CLINTON이 발견되면 $1은 비어 있으므로 Perl 표현식 $1 ? "CLINTON" : "BILL"은 현재 레코드의 끝에 도달할 때까지 이 레코드에 CLINTON인 BILL로 평가됩니다 -p. STDOUT으로 인쇄됩니다.

sed -e 's/BILL\|CLINTON/\n&/g;s/\nBILL/CLINTON/g;s/\nCLINTON/BILL/g' swap

답변2

해결책:

awk '{ for(i=1;i<=NF;i++) { if($i=="BILL") $i="CLINTON"; else if($i=="CLINTON") $i="BILL" } }1'  swap

산출:

CLINTON BILL
BILL CLINTON
CLINTON CLINTON

  • for(i=1;i<=NF;i++)- 모든 필드에 대해 반복(공백을 기본 필드 구분 기호로 처리)

  • if($i=="BILL") $i="CLINTON"- 필드 값이 동일한 경우 BILL- 할당CLINTON

  • else if($i=="CLINTON") $i="BILL"- 그렇지 않은 경우 필드 값이 동일하면 CLINTON- 이를 다음에 할당합니다.BILL

답변3

또 다른 awk 솔루션

awk '{
        while (match($0, /BILL|CLINTON/)) {
            printf "%s", substr($0, 1, RSTART-1);
            $0 = substr($0, RSTART);
            printf "%s", /^BILL/ ? "CLINTON" : "BILL";
            $0 = substr($0, 1+RLENGTH)
        }
        print
    }' swap

관련 정보