의 의미는 무엇입니까 : a; $! N; sed 명령으로?


11
$ (echo hello; echo there) | sed ':a;$!N;s/\n/string/;ta'
hellostringthere

위의 sed명령은 줄 바꾸기 문자를 문자열 "string"으로 바꿉니다. 그러나 :a;$!N;s/\n/string/;ta작은 따옴표 안에 의미가 없습니다 . 나는 중간 부분을 알고있다 s/\n/string/. 그러나 나는 처음 ( :a;$!N;)과 마지막 ( ta) 부분 의 기능을 모른다 .



마지막 부분은 어떻습니까?
Avinash Raj

마지막 대체 명령이 패턴 공간을 수정 한 경우 "t"명령은 명명 된 레이블로 분기됩니다.
xiaodongjie

답변:


17

이것들은 명백히 비밀스러운 sed명령입니다. 구체적으로 (에서 man sed) :

: label
         b 및 t 명령의 레이블입니다.

t label
         마지막 입력 행을 읽은 후 마지막 t 또는 T 명령 이후 as ///가 성공적으로 대체 된 경우 label to branch; label을 생략하면 스크립트 끝에서 분기합니다.

n N 다음 입력 라인을 패턴 공간으로 읽거나 추가합니다.

따라서 게시 한 스크립트는 (가독성을 위해 추가 된 공백)으로 나눌 수 있습니다.

sed ':a;  $!N;  s/\n/string/;  ta'
     ---  ----  -------------  --
      |     |        |          |--> go back (`t`) to `a`
      |     |        |-------------> substitute newlines with `string`
      |     |----------------------> If this is not the last line (`$!`), append the 
      |                              next line to the pattern space.
      |----------------------------> Create the label `a`.

기본적 으로이 작업은 의사 코드로 다음과 같이 작성할 수 있습니다.

while (not end of line){
    append current line to this one and replace \n with 'string'
}

좀 더 복잡한 입력 예제를 사용하면 이것을 더 잘 이해할 수 있습니다.

$ printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;$!N;s/\n/string/;ta'
line1stringline2stringline3stringline4stringline5

!$필요한지 잘 모르겠습니다 . 내가 알 수있는 한, 동일한 출력을 얻을 수 있습니다.

printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;N;s/\n/string/;ta'

1
! $는 마지막 줄 바꿈 IMO와 일치하지 않습니다.
Braiam

@Braiam은 확실 $!하지 않습니다 !$. 그러나, 그것은 또한 수 있습니다 !N하지 $!.
terdon

texinfo 페이지를 구문 분석하려고했지만 !N또는에 대한 참조를 찾지 못했습니다 $!. 그래서 나는 여전히 마지막 줄이 줄 바꿈인지 EOF인지를 계속 생각합니다.
Braiam

4
내가 생각하려고 $!후위 보수 연산자와 주소 '범위'로 - 그래서 $!N(할 N주소를 제외하고 모든 곳에서 $같은과 같은 구문 정말) m,n!d(라인을 제외하고 삭제 모든 m으로는 n).
steeldriver

:아날로그입니다 goto라벨은, 사실 :로 사용 고토 는 사람들이 모두 나오지 사용하여 하루에 백업에 숙지하고 톰슨 쉘 것, 그래서 톰슨 쉘에서 라벨
세르지 Kolodyazhnyy

0

나는 혼동을 많이 볼 수 있기 때문에 나는이 대답을 게시 할 이유를 실행할 때 마지막 줄을 제외 N(라인 주소 문자열을 통해을 $!)과 영업 이익의 의미에 대해 혼동했기 때문에 :a;$!N; 에 나오지 명령 뿐만 아니라에서 특정 하나 그는 게시 .

명령 $!N대신 N마지막 행에서 "중요한"(읽기 유지) 명령이 수행되지 않기 때문에 제안 된 예제 (OP 및 @terdon에 의해)에서 대신 에 사용하는 이점이 명확하지 않습니다 N. (실제로 주소를 제거하면 결과는 동일합니다.)

보다 복잡한 예에서 (예를 들어, this sentence파일에서 두 단어가 한 줄에 나타나고 다른 단어가 두 줄에 나타나는 경우 N가 있음) 명령 의 마지막 줄을 제외하는 것이 중요 할 수 있습니다! 마지막 행을 제외하지 않는 경우, 실행시에 N그 위에, sed히트 EOF(즉,도 명령을 분기 명령 이후의 모든 방지 즉시 종료 t하고 b실행하기 참조).

보여지는 너무 단순한 예 에서 , 중단 된 명령이 실행되지 않으면 아무 것도 수행하지 않기 때문에 실행 된 명령이 실행되지 않기 때문에 안전하게 제거 $!하고 sed실행 N및 리턴에 실패 하게 할 수 있습니다 .s\n

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.