이 sed 스크립트가 어떻게 작동하는지 이해할 수 없습니다.
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed '1s/^$//p;/./,/^$/!d'
cat -s
"하지만 몇 가지 질문이 있습니다" 와 같이 반복되는 빈 줄을 억제합니다 .
- 무엇 때문에
1s/^$//p
? 내가 이해한 바에 따르면 첫 번째 줄이 비어 있어도 아무 작업도 수행되지 않습니다. /./,/^$/
첫 번째 좋아요 이전 에만 일치하고 일치하지 않습니까?^$
Line #1\n\n
Line #1\n\n\n
- sed의 기본 범위가 탐욕스럽지 않습니까?
질문 3을 명확히 하기 위해 다음 테스트를 시도했습니다.
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed -n '/#/,/#/p'
결과 :
Line #1
Line #2
Line #3
(그래서 욕심이 난다)
하지만 내가 시도할 때:
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed -n '/#1/,/#/p'
결과 :
Line #1
Line #2
(이제 욕심은 없는 것 같아요)
답변1
1s/^$//p
첫 번째 줄이 비어 있으면 첫 번째 줄을 인쇄합니다.
/./,/^$/
비어 있지 않은 첫 번째 줄의 줄을 발견된 첫 번째 빈 줄과 일치시킵니다. 정규식 한정자의 의미에서 욕심이 없습니다. sed
파일을 통해 앞으로 보거나 역추적할 수 있는 방법이 없으므로 끝 패턴의 첫 번째 일치에서 중지해야 합니다.
끝 줄 이후에는 시작 줄 검색이 다시 시작되므로 비어 있지 않은 다음 줄이 범위를 다시 시작합니다. 사실상, 범위는 비어 있지 않은 연속 라인과 다음의 첫 번째 빈 라인과 일치합니다.
범위가 사용되므로 /./,/^$/!d
일치하지 않는 모든 행이 삭제됩니다. 여기에는 첫 번째 줄(비어 있는 경우)이 포함되며, 이것이 첫 번째 규칙이 이를 명시적으로 인쇄하는 이유입니다.
규칙이 없으면 1s/^$//p
실제로 "중복"이 아닌 경우에도 첫 번째 행이 비어 있으면 삭제됩니다.
$ echo $'\nfoo' | sed '1s/^$//p;/./,/^$/!d'
foo
$ echo $'\nfoo' | sed '/./,/^$/!d'
foo
$
테스트에서는 /#/,/#/
동일한 패턴으로 시작하고 끝나기 때문에 범위가 약간 다릅니다. Line #1
시작 패턴과 일치하므로(가운데 빈 줄이 인쇄됨) Line #2
끝 패턴과 일치하고(다음 빈 줄은 그렇지 않음) 에 Line #3
범위가 다시 시작됩니다.
다른 하나는 시작 패턴이 이지만 /#1/
입력에서 한 번만 발견됩니다.
답변2
ilkkachu는 sed 문자열의 첫 번째 부분에 대한 덜 분명한 필요성과 "!" 문자가 실제로 반복되는 빈 줄인 일치하지 않는 부분을 제거한다는 사실을 포함하여 명령의 다양한 측면을 다루는 좋은 답변을 제공했습니다.
하지만 이는 더 간단한 옵션이 있는 경우 이상한 접근 방식입니다.사회적 습관, 또는고유한쓸 수 있는.