이 sed 명령이 수행하는 작업: sed '1!G;h'

이 sed 명령이 수행하는 작업: sed '1!G;h'

나는 sed를 더 잘 이해하려고 노력하고 있지만 온라인 문서와 매뉴얼 페이지를 반복적으로 탐색했음에도 불구하고 한 가지 혼란스럽습니다.

내가 그렇게 한다면: ( 이내 bash)

echo "
alpha
beta
gamma" | sed '1!G;h'

이해합니다:

alpha
beta
alpha
gamma
beta
alpha

1!G따라서 라인 1을 제외한 각 입력 라인 뒤에 새 라인이 추가된다는 것을 알고 있습니다 . 그런 다음 h패턴 공간을 예약된 공간에 복사합니다. 그러나 홀드 공간에서는 아무 일도 일어나지 않고 패턴 공간이 출력되어야 합니다. 이 시점에서 나는 다음 과 1!G;h똑같은 출력을 볼 것으로 예상합니다 1!G.

alpha
beta

gamma

보유 공간이 어떻게든 내보내지나요? 예약된 공간이 각 라인의 패턴 공간 다음에 출력된다면 sed 'h'각 라인을 두 배로 늘리는 것은 어떨까요?

아, 저는 이것을 macOS Mojave 5에서 실행하고 있습니다 bash. 어떤 버전을 사용하고 있는지는 모르겠지만 sed최신 macOS와 함께 제공되는 기본 버전입니다.

답변1

G첫 번째 명령은 썼지만 두 번째 명령은 작성한 예약된 공간에서 추가하는 것을 잊었습니다 .

sed h각 주기에서 예약된 공간을 덮는 것이므로 각 행을 두 배로 늘리는 것이 아닙니다.

첫 번째 명령은 다음과 같습니다.

sed '1!G;h' <<END_INPUT
alpha
beta
gamma
END_INPUT

그리고 출력

alpha
beta
alpha
gamma
beta
alpha

첫 번째 줄을 제외한 모든 줄에 대해 구분 줄 바꿈을 사용하여 현재 예약된 공간을 패턴 공간에 추가합니다. 그런 다음 홀드 공간을 패턴 공간으로 덮어씁니다. 각 사이클이 끝나면(입력 라인을 처리한 후) 암시적 p(인쇄) 명령이 있습니다.

이를 다르게 표현하면 "각 입력 줄에 대해 이전의 모든 줄을 역순으로 출력합니다(마지막으로 새 줄)"입니다.

그래서 코드는

  1. alpha패턴 공간으로 읽기 , alpha예약된 공간으로 복사, 인쇄 alpha,
  2. beta패턴 공간으로 읽기 , \nalpha예약된 공간에서 패턴 공간으로 추가, beta\nalpha예약된 공간에 복사, 인쇄 beta\nalpha,
  3. gamma패턴 공간을 읽고 , \nbeta\nalpha예약된 공간에서 패턴 공간으로 추가하고, gamma\nbeta\nalpha예약된 공간에 복사하고, 인쇄합니다 gamma\nbeta\nalpha.

암호

sed '1!G' <<END_INPUT
alpha
beta
gamma
END_INPUT

산출

alpha
beta

gamma

(세 번째 행과 마지막 행은 비어 있습니다.)

sed코드는 입력의 각 줄을 출력하고 첫 번째 줄을 제외한 모든 줄에 추가 줄바꿈을 추가합니다. 그럴 것이기 때문에 이렇게 하는 것이다

  1. alpha패턴 공간을 읽고 , 인쇄하고 alpha,
  2. beta패턴 공간을 읽고 , \n예약된 공간에서 패턴 공간으로 추가하고, 인쇄합니다 beta\n.
  3. gamma패턴 공간을 읽고 , \n예약된 공간에서 패턴 공간에 추가하고, 인쇄합니다 gamma\n.

여기에 예약된 공간을 추가하면 G패턴 공간의 끝에 추가 줄바꿈만 추가됩니다. 왜냐하면 패턴 공간은 항상 비어 있기 때문입니다(쓰기를 하지 않으므로).

답변2

내가 시도한 결과 :

]# echo  -e "a\nb\nc\nd\ne\nf" |sed '1!G;h' 
a
b
a
c
b
a
d
c
b
a
e
d
c
b
a
f
e
d
c
b
a

거꾸로 읽으면 "abcdef", "abcde", "abcd", "abc", "ab", "a"가 됩니다.

그걸 뭐라고 부르나요?

"G"가 추가되고 "h"가 대체되기 때문에 작동합니다. 이를 생략하면 G;h블록 사이에 추가 빈 줄이 생깁니다.


info sed"tac" 예가 있습니다:

sed -n '1!G;$p;h'

한 번만 인쇄하면( -n$p) 결과가 완전히 달라집니다. 마지막 "청크"입니다.sed '1!G;h'


Perl은 (이름이 지정된) 변수를 사용하여 이 알고리즘을 쉽게 에뮬레이트할 수 있습니다.

]# echo -e "a\nb\nc" | perl -ne '$hold = $_ . $hold; print $hold;'
a
b
a
c
b
a

들어오는 라인과 저장된 라인이 병합되는 방식을 반대로 바꿉니다.

]# echo  -e "a\nb\nc" |perl -ne '$hold .= $_; print $hold;'
a
a
b
a
b
c

$_입력라인입니다. H=H+선, H=선+H입니다. info sed이 내용과 다른 미묘한 점을 발견하려면 주의 깊게 읽어야 합니다 .

답변3

더 간단한 것부터 시작해 보겠습니다.

$ seq 4 | sed 'G;h'
1

2
1

3
2
1

4
3
2
1

각 블록은 새로운 숫자를 추가하고 역순으로 인쇄합니다.
왜 이런 일이 발생합니까? 이 과정을 천천히 살펴보겠습니다.

  1. 1sed는 seq (a)의 첫 번째 숫자(첫 번째 줄)를 받습니다. 선은 패턴 공간에 배치됩니다.
  2. 실행될 첫 번째 명령은 이며 G개행 문자를 추가하고 그 뒤에예비 공간현재 배치 공간으로 이동합니다. 먼저 (여기서와 같이) 예약된 공간은 비어 있으므로 sed는 개행 문자와 (공간 보존) 빈 문자열을 현재 패턴 공간에 추가합니다. 간단히 말해서, 입력의 첫 번째 줄에 개행 문자를 추가합니다.
  3. 두 번째 명령은 입니다 h. 패턴 공간을 예약된 공간으로 복사합니다. 이제 예약된 공간은 1개행 문자로 구성됩니다.
  4. 명령 목록이 종료되었으므로 sed에는 옵션이 없기 때문에 sed는 패턴 공간(a 1다음에 개행 문자)을 인쇄합니다 -n. 그런 다음 다음 입력 줄로 반복합니다.
  5. 이제 sed는 두 번째 라인 a를 가져 2와서 패턴 공간에 배치합니다.
  6. 첫 번째 명령은 G입니다. 따라서 sed는 패턴 공간에 추가된 공간( 1위에서 언급한 a 및 줄바꿈, 더 짧은 형식으로 작성됨 : )을 예약합니다. 1\n이제 패턴 공간이 설정되었습니다 2\n1\n.
  7. 패턴 공간에 포함된 내용이 인쇄됩니다. sed는 다시 루프합니다.
  8. 세 번째 G\n2\n1\n에는 3.
  9. 이 패턴 공간을 3\n2\n1\n예약된 공간으로 복사하는 데 사용됩니다 h.
  10. 또한 패턴 공간은 sed 스크립트 끝에 인쇄됩니다.
  11. 마지막 행까지 반복하고 반복합니다.

위의 모든 내용은 라인을 역순으로 캡처하는 것과 동일합니다.

이 스크립트를 사용하면 상황이 더 명확해질 수 있습니다(인용 패턴 공백 사용 l).

$ seq 5 | sed -n 'G;h;l'
1\n$
2\n1\n$
3\n2\n1\n$
4\n3\n2\n1\n$
5\n4\n3\n2\n1\n$

그리고 원본 스크립트에서는 첫 번째 줄에 개행 문자를 추가하지 않습니다.

$ seq 5 | sed -n '1!G;h;l'
1$
2\n1$
3\n2\n1$
4\n3\n2\n1$
5\n4\n3\n2\n1$

이제 알파, 베타 및 감마를 사용하십시오.

$ printf 'alpha\nbeta\ngamma' | sed -n '1!G;h;l'
alpha$
beta\nalpha$
gamma\nbeta\nalpha$

원래 sed 스크립트로 돌아가 보겠습니다.

$ printf 'alpha\nbeta\ngamma' | sed '1!G;h'
alpha
beta
alpha
gamma
beta
alpha

실제로 IMO는 다음과 같아야 합니다.

$ printf 'alpha\nbeta\ngamma' | sed '1!G;h;$!d'
gamma
beta
alpha

모든 줄이 역순으로 되어 마지막 반복만 인쇄됩니다.

관련 정보