sed 패턴 공간과 홀드 공간

sed 패턴 공간과 홀드 공간

방금 이런 일을 겪었는데 이해가 안 돼요.

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\nblub/ p }' file.

고양이 파일은 어디에 있습니까?

 foo
 foo
 bar

왜 이런 일이 발생하는 걸까요? 1!H나에게는 1h패턴 공간을 덮어쓰고 1!H아무 소용이 없기 때문입니다.

그러나 sed oneliner는 잘 작동하는 것 같습니다.

답변1

바라보다@manatwork의 답변실용적인 이유가 1h;1!H있지만 이식성에 대한 메모를 추가하고 싶습니다.

표준 및 이식 가능한 구문은 다음과 같아야 합니다.

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\
blub/p;}'

sed그렇지 않으면 전통적인 Unix 구현과 같은 대부분의 구현에서는 작동하지 않습니다 .

이는 \n명령의 왼쪽에서 이해할 수 있지만 s오른쪽에서는 백슬래시 문자를 사용해야 하고 그 뒤에 실제 개행 문자가 와야 합니다. 또한 ;명령과 사이에 공백이 있어야 하며 그 앞에는 공백이 없어야 합니다.s}p

예약된 공간 대신 ​​패턴 공간에 파일 내용을 저장할 수도 있습니다.

sed -n '
  :1
  $!{
   N;b1
  }
  s/foo\nbar/blah\
blup/p'

그러나 모드 및 저장 공간의 경우 대부분의 sed비 GNU 구현에는 이러한 파일 크기에 제한이 있기 때문에 대부분의 구현에서는 작은 파일만 처리할 수 있습니다(POSIX에서는 8kiB의 데이터만 저장할 수 있어야 함).

이식성을 가지려면 다음을 사용하는 것이 좋습니다 perl.

perl -0777 -ne 'print if s/foo\nbar/blah\nblup/'

perlGNU의 크기는 제한되지 않지만 sed, 각 프로세스의 메모리 사용량에 제한을 설정하지 않으면 시스템 메모리를 모두 사용하게 되므로 시스템 성능에 영향을 미칠 수 있다는 점에 유의하세요.

답변2

1!H가 있는 이유는 1h가 패턴 공간을 덮고 1!H가 쓸모가 없기 때문입니다.

동일한 입력 라인에서 실행되지 않기 때문에 덮어쓰기가 발생하지 않습니다.

1h   # when input line number is 1, copy pattern space to hold space
1!H  # when input line number is not 1, append pattern space to hold space

이는 다음과 같은 이유로 필요합니다 info sed.

`H'
     Append a newline to the contents of the hold space, and then
     append the contents of the pattern space to that of the hold space.

따라서 모든 줄을 추가하기만 사용하면 H첫 번째 줄 앞에 추가 줄 바꿈이 있게 됩니다.

bash-4.2$ seq 3 | sed -n 'H; ${g; p;}'

1
2
3
bash-4.2$ seq 3 | sed -n '1h; 1!H; ${g; p;}'
1
2
3

관련 정보