블록의 주소 뒤에 sed 명령을 그룹화할 수 없는 이유는 무엇입니까?

블록의 주소 뒤에 sed 명령을 그룹화할 수 없는 이유는 무엇입니까?

sed특정 패턴을 제외한 모든 줄을 인쇄 하려고 합니다 . 다음이 작동하지 않는 이유를 이해할 수 없습니다.

sed '/PATTERN/{d;q}' file

sed 스크립트에 대한 제가 이해한 바에 따르면 이 표현식의 결과는 다음과 같습니다.

  • 행이 일치하면 /PATTERN/명령으로 구성된 그룹을 실행합니다.
    1. d패턴 공간 삭제(=현재 라인)
    2. quit는 이후에 현재 패턴 공간을 인쇄합니다.

격리된 상태에서 두 /PATTERN/d작업 /PATTERN/q, 즉 d문제가 있는 행이 삭제되고 종료 q됩니다 .sed그러나 라인을 인쇄한 후, 문서화 된대로. 그러나 이 두 가지 작업을 블록에 결합하면 q무시되는 것 같습니다.

Q대신 GNU 확장으로 사용할 수 있다는 것을 알고 있지만 {d;q}(이것은 예상대로 작동합니다!) 위의 내용이 작동하지 않는 이유와 문서를 어떤 방식으로 오해했는지 이해하고 싶습니다.


내 실제 사용 사례는 파일의 첫 번째 줄이 실제로 패턴과 일치하고 (몇 가지 대체 작업을 수행한 후) 건너뛰기 때문에 (약간) 더 복잡합니다.

sed -e '1{s/>21/>chr21/; n}' -e '/>/{d;q}' in.fasta >out.fasta

그러나 위의 단순화된 사례는 동일한 동작을 나타냅니다.

답변1

특정 패턴이 일치할 때까지 파일의 모든 줄을 출력합니다.아니요일치하는 라인을 출력하려면) 다음을 사용할 수 있습니다.

sed -n '/PATTERN/q; p;' file

여기서 패턴 공간의 기본 출력은 각 사이클이 끝날 때 비활성화됩니다 -n. 대신 각 줄을 명시적으로 인쇄합니다 p. 주어진 패턴이 일치하면 처리를 중지합니다 q.

21fasta 파일의 첫 번째 줄 에서 염색체 21의 이름을 변경한 chr21다음 다음 fasta 헤더 줄에 도달할 때까지 해당 염색체의 DNA를 계속 추출하는 실제 더 긴 명령은 다음과 같이 작성할 수 있습니다.

sed -n -e '1 { s/^>21/>chr21/p; d; }' \
       -e '/^>/q' \
       -e p <in.fasta >out.fasta

또는

sed -n '1 { s/^>21/>chr21/p; d; }; /^>/q; p' <in.fasta >out.fasta

원래 표현식의 문제점은 d새로운 루프를 시작한다는 것입니다(즉, 다음 줄을 강제로 패턴 공간으로 읽어 들여 스크립트의 시작 부분으로 점프합니다). 이는 q절대로 실행되지 않음을 의미합니다 .

GNU가 아닌 시스템에서 구문이 정확하려면 원래 스크립트가 다음과 같아야 합니다 /PATTERN/ { d; q; }. ;뒤에 추가된 내용 에 유의하세요 q(공백은 중요하지 않음).

답변2

d패턴 공간만 삭제하지 마세요: fromPOSIX 사양

[2addr]d

패턴 공간을 삭제하고다음 사이클 시작.

(내 강조)

q명령은 액세스할 수 없습니다.

답변3

이중 주소 형식을 사용하여 동일한 출력을 얻을 수 있습니다(첫 번째 주소만 그 앞의 행과 일치함).

sed -e '/PATTERN/,$d'

그러나 사용된 방법과 달리 q이는 sed각 입력 라인을 계속해서 읽는 것을 의미합니다. 이는 대용량 입력 파일이나 파이프에서 읽을 때 영향을 미칠 수 있습니다.

관련 정보