내가 이거 가지고있어:
sed -i '/^$/d' temp_spec.rb
빈 줄을 제거하고 잘 작동합니다. 5-999 행 (또는 이상적으로 5에서 파일 끝까지)에 대해서만이 작업을 수행하려면 어떻게해야합니까?
나는 시도했다 :
sed -n5,999 -i '/^$/d' temp_spec.rb
sed '5,999!d/^$/d' temp_spec.rb
그러나 둘 다 작동하지 않았습니다 (오류 없음).
내가 이거 가지고있어:
sed -i '/^$/d' temp_spec.rb
빈 줄을 제거하고 잘 작동합니다. 5-999 행 (또는 이상적으로 5에서 파일 끝까지)에 대해서만이 작업을 수행하려면 어떻게해야합니까?
나는 시도했다 :
sed -n5,999 -i '/^$/d' temp_spec.rb
sed '5,999!d/^$/d' temp_spec.rb
그러나 둘 다 작동하지 않았습니다 (오류 없음).
답변:
5 행으로 시작하는 모든 빈 행을 삭제하고 1 행 내지 4 행을 유지하려면 다음을 사용할 수 있습니다.
sed -i '5,${;/^$/d;}' temp_spec.rb
이 {
그룹화 연산자이므로 첫 번째 명령 5,${
은 "5 행부터 입력 끝까지 ( $
) 다음 명령이 일치 할 때까지 실행 }
"을 의미합니다. 사이의 명령 {
과는 }
다시 내부 명령 있도록, 주소 접두어 할 수있다 /^$/d
"시작 사이에 아무 것도 (가없는 경우 수단 ^
)과 끝 ( $
삭제, 라인의)". Sed 명령은로 분리 할 수 있습니다 ;
. (이것은 sed의 잘못 문서화 된 기능입니다. 대부분의 sed 구현에서 지원되지만 완전히 이식 가능하지는 않습니다 .) Hauke가 지적한 것처럼 ;
after {
는 선택 사항입니다. }
그러나 이전의 것이 필요합니다.
5 행으로 시작하는 모든 빈 행을 삭제하고 1 행 내지 4 행을 삭제하려는 경우 더 쉽습니다.
sed -i '1,4d;/^$/d' temp_spec.rb
;
에게도 선두없이 작동합니다 .
;
.
sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb
편집 1 :
따라서 이것을 설명해야합니다.
불필요하게 복잡합니다. 주소 범위가에 허용되는지 몰랐습니다 {}
. 따라서 "빈 줄 삭제"를 다르게 표현해야했습니다. 핵심 명령은 t
sed의 방법입니다 if ... then
. T
더 쉬웠지만 GNU sed에서만 사용할 수 있습니다. 매뉴얼 페이지를 인용합니다.
t label : 마지막 입력 행을 읽은 후 마지막 t 또는 T 명령 이후 as ///가 성공적으로 대체 된 경우 label to branch; label을 생략하면 스크립트 끝에서 분기합니다.
나는 유명한 s
명령을 남용합니다 . 아무것도 바꾸지 말고 라인이 비어 있는지 테스트하십시오. 따라서 빈 줄을 빈 줄로 바꿉니다 (어쨌든 삭제 된 줄을 대체물로 사용할 수 있습니다).
경우 s
에 "교체"를 수행 한 후 행이 비어 있습니다. 이 경우 명령 d
이 실행됩니다. 그렇지 않으면 아무것도 수행되지 않습니다. 으로는 t
의 경우에는 이동하지 않습니다 s
나는 분기 명령을 필요로 작용 b
스크립트의 끝으로 이동합니다. : label
분기 대상입니다. 당시와 마찬가지로 goto
암흑 시대 (sed가 발명되었을 때 ... te-hee).
또 다른 옵션은 s
비어 있지 않은 모든 행 을 "대체"하여 s
더 복잡하지만 나머지 명령을보다 쉽게 만드는 것입니다.
sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input
^..*$
"빈 줄 없음"을 \1
의미하고 "첫 번째 괄호의 내용 "을 의미합니다.