출력의 두 번째 줄에서 다른 명령을 어떻게 실행할 수 있나요?
예를 들어, echo foo | sed p
어떤 출력이 있습니까?
foo
foo
sed 's/foo/bar/'
나는 그 중 하나를 실행하여 얻고 싶습니다 .
bar
foo
답변1
존재하다
$ echo foo | sed p
foo
foo
첫 번째 것은 foo
명령에 의해 인쇄되고 p
, 두 번째 것은 패턴 공간이 루프의 끝(다음 줄을 읽기 직전)에 인쇄되기 -n
때문에 인쇄되지 않습니다.sed
foo
그래서 그것을 얻으려면 bar
다음과 같습니다.
$ echo foo | sed 'p;s/foo/bar/'
foo
bar
또는:
$ echo foo | sed -n 'p;s/foo/bar/p'
foo
bar
bar
대체가 있는 경우에만 인쇄합니다( s
대체에 성공하면 플래그가 있는 명령으로).p
bar
, 를 얻으려면 이전 원래 줄을 foo
가져와 h
교체 결과를 인쇄한 후 복원합니다.
$ echo foo | sed 'h;s/foo/bar/p;g'
bar
foo
답변2
데이터의 첫 번째 줄에 영향을 주지 않는 명령을 실행하려면 서브셸에서 해당 명령을 실행하고 다음과 같이 첫 번째 줄을 읽고 출력하는 명령을 앞에 붙입니다.
read -r line; echo "$line" # pass first line unmodified
sed 's/foo/bar/' # operate on rest of lines
전체 예는 다음과 같습니다.
$ echo foo | sed p | ( read -r line; echo "$line"; sed 's/foo/bar/')
foo
bar
답변3
입력 줄 번호에 따라 다른 작업을 수행할 수 있는 명령으로 이를 파이프하는 것이 더 좋습니다.
예를 들어 다음과 같습니다 sed
.
$ printf 'foo\nfoo\n' | sed '2,$s/foo/bar/'
foo
bar
이는 sed의 주소 지정 구문을 사용하여 작업을 2 줄 s/foo/bar/
부터 파일 끝까지( )까지의 줄로 제한합니다.2,$
( man sed
GNU 버전, 더 읽기 쉽게 형식을 약간 변경함):
Sed 명령은 주소 없이 실행될 수 있습니다. 이 경우 명령은 주소가 있는 모든 입력 라인에서 실행됩니다. 이 경우 명령은 해당 주소와 일치하는 입력 라인에서만 실행됩니다. 이 경우 명령은 첫 번째 주소에서 시작하여 두 번째 주소까지 이어지는 라인의 포함 범위와 일치하는 모든 입력 라인에 대해 실행됩니다.
주소 범위에 관해 주의할 세 가지 사항은 다음과 같습니다.
구문은 addr1, addr2입니다(즉, 쉼표로 주소를 구분함).
addr2가 이전 행을 선택하더라도 addr1과 일치하는 행은 항상 허용됩니다.
addr2가 정규식인 경우 addr1과 일치하는 행은 테스트되지 않습니다.
또는 awk
:
$ printf 'foo\nfoo\n' | awk 'NR > 1 {gsub(/foo/,"bar")};1'
foo
bar
또는 펄:
$ printf 'foo\nfoo\n' | perl -p -e 's/foo/bar/ if $. > 1'
foo
bar
awk 및 perl 버전은 행 번호( NR
awk의 경우, $.
perl의 경우)가 1보다 큰지 여부를 테스트합니다.