sed '1! G; h; $! d'명령은 파일 내용을 어떻게 바꾸나요?


20

내 질문은 관련이 sed주어진 - 특정 솔루션 이 답변 이 질문에 대한 역 grepping . sed/의 grep내가 해독 할 수없는 오전 솔루션은 하나를 다음입니다 :

sed '1!G;h;$!d' file

누군가이 명령을 해독 할 수 있습니까?

나는 VI (M) 지식에서 G가 파일의 마지막 줄을 나타내고 sed에서 bang (!) 다음에 주소 작업이 grep -v그 줄과 일치하지 않는다고 말하는 것을 알고 있습니다. 그러나 전체적으로 위의 인라인 sed 스크립트는 저쪽에 있습니다.


3
... 매우 느리게 ...
mikeserv

1
mikeserv가 암시합니다. 이 까다로운 sed레시피는 파일에서 라인을 뒤집는 매우 비효율적 인 방법 (O (n ^ 2 / 2) 복잡성)입니다. 줄 수가 많은 파일의 경우 속도가 느려집니다. 훨씬 효율적인 라인 순서 반전 대안은 tacGNU coreutils를 참조하십시오 .
arielf

답변:


35

파일을 한 줄씩 뒤집습니다.

sed '1! G; h; $! d' 파일

첫째, sed보류 영역패턴 공간을 . 특정 명령에 집중하기 전에 이들을 구별해야합니다.

sed새 줄을 읽고, 그것은 패턴 공간에로드됩니다. 따라서 새 줄을 처리 할 때마다 해당 공간을 덮어 씁니다. 반면에, 홀드 공간은 전체 처리에서 일관되며 나중에 사용하기 위해 값을 저장할 수 있습니다.


명령으로 :

이이 문에서 3 개 명령은 다음과 같습니다 1!G, h그리고$!d

  • 1!GG명령이 첫 번째 행을 제외한 모든 행에서 실행 됨을 의미합니다 (를 !무시합니다 1). 홀드 공간에있는 것을 패턴 공간 G추가 하는 것을 의미 합니다.

  • h모든 라인에 적용됩니다. 그것은 복사 패턴 홀드 공간에 공간 (및 덮어 쓰기를).

  • $!d마지막 줄을 제외한 모든 줄에 적용됩니다 ( $마지막 줄을 나타내며 !무시합니다). d행을 삭제하는 명령입니다 (패턴 공간).


  1. 이제 첫 번째 줄을 읽을 sedh명령을 실행하십시오 . 첫 번째 줄이 보류 공간에 복사됩니다. 그런 다음 $!조건 과 일치하므로 삭제됩니다 . sed두 번째 줄을 계속합니다.
  2. 두 번째 줄은 조건 1!(첫 번째 줄이 아님) 과 일치 하므로 보류 공간 (첫 번째 줄이 있음)이 패턴 공간 (두 번째 줄이 있음)에 추가됩니다. 그 후, 패턴 공간에는 두 번째 줄 다음에 첫 번째 줄이 있으며 줄 바꿈으로 구분됩니다. 이제 h명령이 적용됩니다 (모든 행에서와 같이). 패턴 공간에있는 모든 것이 보류 공간에 복사됩니다. 세 번째 문장 ( $!d)이 적용됩니다. 행이 패턴 공간에서 삭제됩니다.
  3. 2 단계는 이제 모든 회선으로 수행됩니다. 마지막 줄로 건너 뜁니다.
  4. 마지막 줄 ( $)에서 거의 모든 2 단계가 완료되지만 삭제 부분 ( d) 은 수행되지 않습니다 . sed로 호출하지 않으면 -n각 입력 행에 대한 처리가 끝날 때 패턴 공간을 자동으로 인쇄합니다. 따라서 삭제하지 않으면 패턴 공간이 인쇄됩니다. 이제 모든 줄을 역순으로 포함합니다 .

1
@Geek 아니요,이 h명령은 패턴 공간을 보류 공간으로 복사합니다 sed. 스크립트가 끝나면 바이너리가 종료 되었기 때문에 모든 것이 지워집니다.
혼돈

2
보류 공간을 vim의 레지스터처럼 생각할 수 있습니까? 그들은 또한 번호가 있습니까? 아니면 그들 중 하나만 있습니까?
Geek

2
@Geek In sed에는 하나의 보류 공간 만 있습니다. 무언가를 포함 할 수있는 변수와 같습니다.
혼돈

1
@ user1717828 처리하지 않으면 첫 번째 줄이 인쇄되지 않습니다. sed가 호출되지 않으므로 -n마지막을 제외한 모든 행을 삭제해야합니다. 마지막 줄에서 sed는 홀드 공간에서 패턴 공간까지 모든 것을 추가합니다. 그리고 d명령이 실행되지 않기 때문에 행이 인쇄됩니다 (이 행에는 이제 전체 파일이 반전되었습니다).
혼돈

1
(1) OP의 하위 질문 / 관찰 (의견에서)은“ 마지막 줄h명령 은 작동하지 않습니다. 그가 맞아; 경우 가공하는된다 마지막 입력 라인 은은 (패턴 영역에 추가하기 위하여) 보류 영역을 판독하고 복사 보류 영역, 패턴 영역 을 다시 참조하지 않는다 . 우리는 또는 말할 수 있습니다 . (2) 라고 말하면 사용 을 피할 수 있습니다. sedGhsed 'G;$!h;$!d'sed 'G;$!{h;d}'dsed -n 'G;h;$p'
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.