Sed &awk 노트의sed 편: 고급 명령 (1)

7385 단어
전편에서 소개한 기초 명령은 모두 줄을 향한 것이다. 일반적인 상황에서 이런 처리는 아무런 문제가 없지만 일치하는 내용이 두 줄에서 엇갈릴 때 문제가 생긴다. 가장 뚜렷한 예는 일부 영어 단어가 두 줄로 나뉘는 것이다.다행히도,sed는 여러 줄의 내용을 패턴 공간으로 읽을 수 있도록 해 줍니다. 그러면 여러 줄을 뛰어넘는 내용과 일치할 수 있습니다.이 노트는 주로 이 명령들을 소개하는데, 이 명령들은 여러 줄 모드 공간을 만들고 처리할 수 있다.그 중에서 N/D/P 세 개의 여러 줄 명령은 각각 소문자 n/d/p 명령에 대응하고 후자는 우리가 전편에서 소개한 바와 같다.그것들의 기능은 유사한데, 차이점은 명령이 영향을 주는 내용이 다르다는 데 있다.예를 들어 D 명령은 d 명령과 마찬가지로 모드 공간의 내용을 삭제한다. 단지 d 명령은 모드 공간의 모든 내용을 삭제하고 D 명령은 모드 공간의 첫 줄만 삭제한다.
다음 줄 읽기: N 명령은 다음 줄의 내용을 현재 모드 공간으로 읽습니다. 그러나 n 명령이 다른 부분은 N 명령이 현재 모드 공간의 줄을 직접 출력하지 않고 다음 줄을 현재 모드 공간에 추가합니다. 두 줄 사이를 리턴 문자로 연결합니다. 아래 그림과 같습니다. 모드 공간이 여러 줄을 포함하면 정규 표현식^/$기호의 뜻이 바뀝니다.^는 일치하는 모드 공간의 시작이지 행수가 아닙니다. $는 일치하는 모드 공간의 마지막 위치입니다. 행미가 아닙니다.책에서 제시한 첫 번째 예는 다음 텍스트의 "Owner and Operator Guide"를 "Installation Guide"로 대체하는 것입니다. 이 글의 첫머리에서 말했듯이 Owner and Operator Guide는 두 줄에 걸쳐 있습니다.

Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
우리는 N 명령으로 착수한다.

$ sed '/Operator$/{N;s/Owner and Operator
Guide/Installation Guide/}' text Consult Section 3.1 in the Installation Guide for a description of the tape drives available on your system.
그러나 이 예는 두 가지 한계가 있다.
  • Owner and Operator Guide의 분할 위치를 알고 있습니다.
  • 교체 명령을 집행한 후 앞뒤 두 줄이 연결되어 이 줄이 너무 길다.

  • 두 번째는 다음과 같습니다.
    
    $ sed '/Operator$/{N;s/Owner and Operator
    Guide /Installation Guide
    /}' text Consult Section 3.1 in the Installation Guide for a description of the tape drives available on your system.
    이제 첫 번째 전제를 없애고 우리는 더욱 복잡한 테스트 텍스트를 도입했다. 이 텍스트에는 Owner and Operator Guide가 한 줄에 있고 여러 줄을 뛰어넘는 경우도 있다.
    
    $ cat text
    Consult Section 3.1 in the Owner and Operator
    Guide for a description of the tape drives
    available on your system.
    
    Look in the Owner and Operator Guide shipped with your system.
    
    Two manuals are provided including the Owner and
    Operator Guide and the User Guide.
    
    The Owner and Operator Guide is shipped with your system.
    
    앞서 수행한 명령을 다음과 같이 수정합니다.
    
    $ sed 's/Owner and Operator Guide/Installation Guide/
    /Owner/{
    N
    s/ *
    / / s/Owner and Operator Guide */Installation Guide\ / }' text Consult Section 3.1 in the Installation Guide for a description of the tape drives available on your system. Look in the Installation Guide shipped with your system. Two manuals are provided including the Installation Guide and the User Guide. The Installation Guide is shipped with your system.
    여기서 우리는 먼저 한 줄에 나타난 Owner and Operator Guide를 Installation Guide로 바꾼 다음에 Owner와 일치하는 줄을 찾아 다음 줄의 내용을 모드 공간으로 읽고 중간에 있는 줄 바꾸기를 빈칸으로 바꾼 다음에 마지막으로 Owner and Operator Guide를 바꿉니다.설명하기는 매우 간단하지만, 중간에는 그래도 약간의 비결이 있다.예를 들어 여기 맨 앞에 있는 s/Owner and Operator Guide/Installation Guide/명령이 불필요하다고 생각할 수 있습니다. 이 문장을 삭제하면 다음과 같습니다.
    
    $ sed '/Owner/{
    > N
    > s/ *
    / / > s/Owner and Operator Guide */Installation Guide\ > / > }' text Consult Section 3.1 in the Installation Guide for a description of the tape drives available on your system. Look in the Installation Guide shipped with your system. Two manuals are provided including the Installation Guide and the User Guide. The Owner and Operator Guide is shipped with your system.
    가장 뚜렷한 문제는 마지막 줄이 바뀌지 않았다는 것이다. 마지막 줄이 모드 공간에 읽힌 후에 Owner와 일치하고 N 명령을 실행하면 다음 줄로 읽는다. 그러나 현재 마지막 줄이기 때문에 N 읽기 교체는sed가 종료할 수 있음을 알려주고sed는 다음 교체 명령을 계속 실행하지 않는다(
    주: 책에서 마지막 줄은 출력되지 않는다고 했는데, 이쪽에서 테스트하면 출력됩니다.그래서 N을 사용할 때 현재 행위의 마지막 줄을 읽을 때 다음 줄의 내용을 읽지 않는다는 판단을 추가해야 합니다: $!N, 이 기능은 많은 경우에 유용하며 변경 후 다시 실행됩니다.
    
    $ sed '/Owner/{
    > $!N
    > s/ *
    / / > s/Owner and Operator Guide */Installation Guide\ > / > }' text Consult Section 3.1 in the Installation Guide for a description of the tape drives available on your system. Look in the Installation Guide shipped with your system. Two manuals are provided including the Installation Guide and the User Guide. The Installation Guide is shipped with your system.
    위에서 N의 사용법을 예로 설명하기 위해서일 뿐 해결 방안이 반드시 가장 좋은 것은 아닐 수도 있다.
    줄 삭제: D 이 명령은 모드 공간의 첫 번째 줄의 내용을 삭제하고 그에 대응하는 작은 d 명령은 모드 공간의 모든 내용을 삭제합니다.
    모드 공간에서 내용이 비어 있지 않으면 D는 새 줄을 읽지 않고, 반대로 최초의 편집 명령으로 돌아가 모드 공간의 나머지 내용에 중요한 역할을 한다.뒤의 반구는 이해하기 어려우니 책 속의 한 예로 해석해 보아라.이제 다음과 같이 줄 사이에 빈 줄이 있는 텍스트 파일이 있습니다.
    
    $ cat text
    This line is followed by 1 blank line.
    
    This line is followed by 2 blank lines.
    
    
    This line is followed by 3 blank lines.
    
    
    
    This line is followed by 4 blank lines.
    
    
    
    
    This is the end.
    
    현재 우리는 여분의 빈 줄을 삭제하고 여러 개의 빈 줄을 한 줄로 줄여야 한다.만약 우리가 d 명령을 사용하여 삭제한다면 매우 간단한 논리:
    
    $ sed '/^$/{N;/^
    $/d}' text This line is followed by 1 blank line. This line is followed by 2 blank lines. This line is followed by 3 blank lines. This line is followed by 4 blank lines. This is the end.
    우리는 기수 개수의 연결 빈 줄이 한 줄로 통합되었지만 짝수 개수는 모두 삭제되었다는 이상한 결과를 발견할 수 있다.이 때문에 위의 명령을 다시 번역해야 합니다. 빈 줄과 일치하면 다음 줄도 모드 공간으로 읽고, 다음 줄도 빈 줄이면 모드 공간의 내용이 일치해야 합니다. 따라서% $와 일치하기 때문에 d 명령을 실행하면 모드 공간의 내용을 비웁니다. 그 결과 연결된 두 줄이 모두 삭제됩니다.이렇게 하면 왜 홀수 개의 공행이 연결된 상황에서 정상적이고 짝수 개수에 문제가 있는지 이해할 수 있다.이런 상황에서 우리는 D명령으로 처리해야 한다. 이렇게 하면 예상한 결과를 얻을 수 있다.
    
    $ sed '/^$/{N;/^
    $/D}' text This line is followed by 1 blank line. This line is followed by 2 blank lines. This line is followed by 3 blank lines. This line is followed by 4 blank lines. This is the end.
    D 명령은 모드 공간의 첫 줄만 삭제하고 삭제한 후에 다시 모드 공간의 내용에서 편집 명령을 집행한다. 이것은 하나의 순환을 형성하는 것과 유사하며 연결된 것이 모두 빈 줄이라는 전제 조건이다.빈 줄이 일치할 때, N은 다음 줄의 내용을 읽습니다. 이 때 일치하는 ^$는 모드 공간의 첫 줄을 삭제합니다.현재 모드 공간의 내용이 비어 있습니다. 편집 명령을 다시 실행합니다. 이 때/^$/과 일치합니다.다음 줄을 계속 읽습니다. 현재 줄이 빈 줄일 때 이전의 동작을 반복합니다. 그렇지 않으면 현재 모드 공간의 내용을 출력합니다.결과적으로 여러 개의 빈 줄이 연속되고 마지막 빈 줄만 출력을 보존하며 나머지는 삭제되었습니다.이런 결과야말로 우리가 최초로 바라는 것이다.
    인쇄 줄: P P 명령은 p 명령과 같이 인쇄 모드 공간의 내용입니다. 전자는 인쇄 모드 공간의 첫 번째 줄만 인쇄하고 후자는 모든 내용을 인쇄합니다.편집 명령이 모두 실행된 후에sed는 기본적으로 모드 공간의 내용을 출력하기 때문에 일반적인 경우 p와 P 명령은 n 옵션과 함께 사용됩니다.그러나 예외적으로 편집 명령의 실행 절차가 바뀐 경우도 있다. 예를 들어 N, D 등이다.많은 경우 P 명령은 N 명령 이후, D 명령 이전에 사용됩니다.이 세 명령을 합치면 한 사람이 입력한 출력의 순환을 형성할 수 있고 매번 한 줄만 인쇄할 수 있다. 한 줄만 읽은 후에 N은 다음 줄을 계속 읽고 P 명령은 첫 줄을 인쇄하며 D 명령은 첫 줄을 삭제하고 실행 절차는 처음부터 이 과정을 반복한다.
    
    $ echo -e "line1
    line2
    line3" | sed '$!N;P;D'
    그러나 여러 줄 명령을 사용할 때 각별히 조심해야 한다. 자신의 뇌로 집행 과정을 한 번 연산해야 한다. 그렇지 않으면 실수하기 쉽다. 예를 들어 다음과 같다.
    
    $ echo -e "line1
    line2
    line3" | sed -n 'N;1P'
    첫 번째 줄의 내용을 인쇄하기를 기대할 수 있습니다. 사실상 출력이 되지 않았습니다.왜냐하면 N이 두 번째 줄을 계속 읽은 후에 현재 줄 번호가 2가 되었기 때문이다. 우리는 두 번째 노트에서 말했듯이 줄 번호는sed가 내부에서 유지하는 계수 변수일 뿐이다. 새로운 줄을 읽을 때마다 줄 번호는 1을 더한다.
    
    $ echo -e "line1
    line2
    line3" | sed -n '$!N;=' 2 3
    우리는 여전히 Unix System을 Unix Operating System으로 교체하는 것을 예로 삼아 N/P/D 세 명령이 어떻게 협조하여 사용되는지 소개한다.예제 텍스트는 다음과 같습니다. 예를 들어 편리함을 위해 이 텍스트는 세 줄만 있고 하나의 순환적인 처리 과정을 보여줄 수 있습니다.
    
    $ cat text
    The UNIX
    System and UNIX
    ...
    
    실행된 명령:
    
    $ sed '/UNIX$/{
    > N
    > s/
    System/ Operating &/ > P > D > }' text The UNIX Operating System and UNIX ...
    집행 과정은 다음과 같다. 상기 세 가지 명령의 용법은 앞에서 소개한 기초 명령과 완전히 다르기 때문에 일부 학우들은 접촉한 적이 없을 것이다.다음 편에서는 더 많은 고급 명령을 소개하면서 공간 유지(Hold Space)라는 새로운 개념을 도입할 것이다.

    좋은 웹페이지 즐겨찾기