$ (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
) 부분 의 기능을 모른다 .
답변
이것들은 명백히 비밀스러운 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'
답변
나는 혼동을 많이 볼 수 있기 때문에 나는이 대답을 게시 할 이유를 실행할 때 마지막 줄을 제외 N
(라인 주소 문자열을 통해을 $!
)과 영업 이익의 의미에 대해 혼동했기 때문에 :a;$!N;
에 나오지 명령 뿐만 아니라에서 특정 하나 그는 게시 .
명령 $!N
대신 N
마지막 행에서 “중요한”(읽기 유지) 명령이 수행되지 않기 때문에 제안 된 예제 (OP 및 @terdon에 의해)에서 대신 에 사용하는 이점이 명확하지 않습니다 N
. (실제로 주소를 제거하면 결과는 동일합니다.)
보다 복잡한 예에서 (예를 들어, this sentence
파일에서 두 단어가 한 줄에 나타나고 다른 단어가 두 줄에 나타나는 경우 N
가 있음) 명령 의 마지막 줄을 제외하는 것이 중요 할 수 있습니다! 마지막 행을 제외하지 않는 경우, 실행시에 N
그 위에, sed
히트 EOF
(즉,도 명령을 분기 명령 이후의 모든 방지 즉시 종료 t
하고 b
실행하기 참조).
보여지는 너무 단순한 예 에서 , 중단 된 명령이 실행되지 않으면 아무 것도 수행하지 않기 때문에 실행 된 명령이 실행되지 않기 때문에 안전하게 제거 $!
하고 sed
실행 N
및 리턴에 실패 하게 할 수 있습니다 .s
\n