[linux] sed의 ‘홀드 스페이스’와 ‘패턴 스페이스’의 개념
sed의 두 가지 개념 인 홀드 공간과 패턴 공간이 혼란 스럽습니다. 누군가 그들을 설명 할 수 있습니까?
다음은 매뉴얼의 일부입니다.
h H Copy/append pattern space to hold space. g G Copy/append hold space to pattern space. n N Read/append the next line of input into the pattern space.
이 6 가지 명령은 정말 혼란 스럽습니다.
답변
sed가 파일을 한 줄씩 읽을 때 현재 읽은 줄은 패턴 버퍼 (패턴 공간)에 삽입됩니다 . 패턴 버퍼는 현재 정보가 저장되는 스크래치 패드 인 임시 버퍼와 같습니다. sed에게 인쇄를 지시하면 패턴 버퍼를 인쇄합니다.
홀드 버퍼 / 홀드 공간은 sed가 다른 라인을 처리 할 때 무언가를 잡아서 저장하고 나중에 재사용 할 수있는 장기 저장 공간과 같습니다. 보류 공간을 직접 처리하지 않고 대신 복사하거나 패턴 공간에 추가해야합니다. 예를 들어, print 명령 p
은 패턴 공간 만 인쇄합니다. 마찬가지로 s
패턴 공간 에서 작동합니다.
다음은 그 예입니다.
sed -n '1!G;h;$p'
(-n 옵션은 행의 자동 인쇄를 억제합니다)
여기에는 세 가지 명령이 있습니다. 1!G
, h
및 $p
. 1!G
주소 1
(첫 번째 줄)가 있지만 !
명령이 첫 번째 줄을 제외한 모든 곳 에서 실행된다는 의미입니다 . $p
반면에 마지막 줄에서만 실행됩니다. 그래서 일어나는 일은 다음과 같습니다.
- 첫 번째 줄을 읽고 패턴 공간에 자동으로 삽입
- 첫 번째 줄에서는 첫 번째 명령이 실행되지 않습니다.
h
첫 번째 줄을 보류 공간에 복사합니다 . - 이제 두 번째 줄은 패턴 공간에 있던 모든 것을 대체합니다.
- 두 번째 줄에서 먼저를 실행
G
하여 보류 버퍼의 내용을 패턴 버퍼에 추가하고 줄 바꿈으로 구분합니다. 이제 패턴 공간에는 두 번째 줄, 줄 바꿈 및 첫 번째 줄이 포함됩니다. - 그런 다음
h
command는 패턴 버퍼의 연결된 내용을 보류 공간에 삽입하여 이제 반전 된 행 2와 1을 보유합니다. - 3 번 행으로 이동합니다. 위의 지점 (3)으로 이동합니다.
마지막으로 마지막 행을 읽고 보류 공간 (역순으로 이전의 모든 행을 포함)이 패턴 공간에 추가 된 후 패턴 공간이로 인쇄됩니다 p
. 짐작했듯이 위는 tac
명령이 하는 일을 정확히 수행합니다. 파일을 반대로 인쇄합니다.
답변
@Ed Morton : 여기에 동의하지 않습니다. 나는 sed
매우 유용하고 간단하다는 것을 알았다 (패턴의 개념을 파악하고 버퍼를 유지하면).
예를 들어, 호스트 이름과 각 호스트에 대한 몇 가지 정보가있는 텍스트 파일을 가져 와서 그 사이에 내가 신경 쓰지 않는 쓰레기가 많이 들어갑니다.
Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
나에게 호스트 이름과 해당 info
줄을 가져 오는 awk 스크립트 는 sed로 할 수있는 것보다 조금 더 걸릴 것입니다.
sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt
출력은 다음과 같습니다.
Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!
( Host: foo1
출력에 두 번 나타납니다.)
설명:
-n
명시 적으로 인쇄되지 않는 한 출력을 비활성화합니다.- 첫 번째 일치,
Host:
행을 찾아서 보류 버퍼 (h)에 넣습니다. - 두 번째 일치는 다음 Info : 행을 찾지 만 먼저 패턴 버퍼에서 현재 행을 홀드 버퍼와
Host:
교환 (x)하고 행을 인쇄 (p) 한 다음 Info : 행을 다시 교환 (x)하고 인쇄 (p)합니다.
예, 이것은 단순한 예이지만 간단한 sed one-liner로 빠르게 처리 된 일반적인 문제라고 생각합니다. 주어진 예측 가능한 시퀀스에 의존 할 수없는 작업과 같이 훨씬 더 복잡한 작업의 경우 awk가 더 적합 할 수 있습니다.
답변
@January의 답변과 예는 좋지만 설명이 충분하지 않았습니다. 정확히 어떻게 sed -n '1!G;h;$p'
작동 하는지 이해할 수있을 때까지 많은 것을 검색하고 배워야했습니다 . 그래서 저 같은 사람을 위해 명령에 대해 자세히 설명하고 싶습니다.
먼저 명령이 수행하는 작업을 살펴 보겠습니다.
$ echo {a..d} | tr ' ' '\n' # Prints from 'a' to 'd' in each line
a
b
c
d
$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;$p'
d
c
b
a
tac
명령 처럼 입력을 반전합니다 .
sed
한 줄씩 읽으므로 각 줄의 패턴 공간 과 유지 공간 에서 어떤 일이 발생하는지 살펴 보겠습니다 . 마찬가지로 h
명령 복사 보류 공간 패턴 영역의 내용을 모두 공간은 동일한 텍스트있다.
Read line Pattern Space / Hold Space Command executed
-----------------------------------------------------------
a a$ h
b b\na$ 1!G;h
c c\nb\na$ 1!G;h
d d\nc\nb\na$ 1!G;h;$p
마지막 줄에는 다음과 같은 형식으로 $p
인쇄 d\nc\nb\na$
됩니다.
d
c
b
a
각 행의 패턴 공간을 보려면 l
명령을 추가 할 수 있습니다 .
$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;l;$p'
a$
b\na$
c\nb\na$
d\nc\nb\na$
d
c
b
a
sed가 어떻게 작동하는지 이해하는 비디오 튜토리얼을 시청하는 것이 매우 도움이 되었습니다. 그 사람은 각 공간이 단계별로 어떻게 사용되는지 보여줍니다. 보류 간격은 4 번째 자습서에서 참조되지만 .NET에 익숙하지 않은 경우 모든 비디오를 시청하는 것이 좋습니다 sed
.
또한 GNU sed 문서 와 Bruce Barnett의 Sed 튜토리얼 은 매우 좋은 참고 자료입니다.