sed
특정 패턴을 제외한 모든 줄을 인쇄 하려고 합니다 . 다음이 작동하지 않는 이유를 이해할 수 없습니다.
sed '/PATTERN/{d;q}' file
sed 스크립트에 대한 제가 이해한 바에 따르면 이 표현식의 결과는 다음과 같습니다.
- 행이 일치하면
/PATTERN/
명령으로 구성된 그룹을 실행합니다.d
패턴 공간 삭제(=현재 라인)q
uit는 이후에 현재 패턴 공간을 인쇄합니다.
격리된 상태에서 두 /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
.
21
fasta 파일의 첫 번째 줄 에서 염색체 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
답변3
이중 주소 형식을 사용하여 동일한 출력을 얻을 수 있습니다(첫 번째 주소만 그 앞의 행과 일치함).
sed -e '/PATTERN/,$d'
그러나 사용된 방법과 달리 q
이는 sed
각 입력 라인을 계속해서 읽는 것을 의미합니다. 이는 대용량 입력 파일이나 파이프에서 읽을 때 영향을 미칠 수 있습니다.