bash에서 awk를 사용하여 줄 번호를 올바르게 찾고 sed를 사용하여 삭제하는 방법은 무엇입니까?

bash에서 awk를 사용하여 줄 번호를 올바르게 찾고 sed를 사용하여 삭제하는 방법은 무엇입니까?

Bash에서 파일의 특정 줄을 삭제하고 싶습니다.

sed현재 내가 하고 있는 일은 이 줄을 삭제 하기 위해 줄 번호를 가져와서 전달하는 것입니다 .

awk '/qr/{ print NR; exit }' test | sed -i "${1}d" test

위젯은 awk제대로 작동하지만 이 상태에서는 sed위젯이 파일(test라는 이름)의 모든 내용을 삭제합니다.

그러나 변수 없이 이 작업을 수행하면 다음과 같습니다.

sed -i '1d' test

좋은 결과.

내가 뭘 잘못했나요?

답변1

${1}현재 컨텍스트의 첫 번째 인수로 대체되며 awk예제의 출력에서 ​​아무것도 읽지 않습니다.

awksum 을 유지하려는 경우 sed한 가지 방법은 의 출력을 awk변수에 저장하는 것입니다.

line=$(awk '/qr/{ print NR; exit }' test); sed -i "${line}d" test

하지만 파일에 "qr"이 포함된 줄이 없으면 제대로 작동하지 않습니다.

더 나은 접근 방식은 다음을 사용하는 것입니다 sed.

sed -i "/qr/d" test

그러나 이렇게 하면 첫 번째 줄뿐만 아니라 일치하는 모든 줄이 삭제됩니다.

AWK(또는 gawkGNU 구현,버전 4.1.0부터)는 위와 동일하다.

gawk -i inplace '!/qr/' test

또는 첫 번째 인스턴스만 바꾸려면

gawk -i inplace '/qr/ && !i { i++; next; } 1' test

답변2

다음 입력 파일이 주어지면:

$ cat file
foo
qr
bar

정말로 이 방법을 사용하고 싶다면 다음과 같이 하십시오( -i그렇지 않으면 sed의 효과를 볼 수 있습니다).

$ awk '/qr/{print NR; exit}' file | xargs -n 1 -I {} sed '{}d' file
foo
bar

하지만 물론 이것은 무의미한 xargs+sed 파이프라인이므로 수행해야 할 작업은 다음과 같습니다.

awk '!f && /qr/{f=1; next} 1' file > tmp && mv tmp file

또는 이를 지원하는 최신 버전의 gawk를 사용하세요.

awk -i inplace '!f && /qr/{f=1; next} 1' file

답변3

패턴의 첫 번째 발생만 제거한다고 가정하면 awk정확하게 다음을 사용할 수 있습니다.

awk '/qr/{if (!i++) next}1' test

그러면 1첫 번째 일치하는 줄( )을 제외한 모든 줄이 인쇄됩니다 /qr/( i여전히 0이므로 next"인쇄" 작업이 적용되기 전에 명령이 실행됩니다).

"내부" 편집 기능이 필요한 경우 sed -i,그리고GNU > 4.1.0을 사용하는 경우 awk"inplace" 확장을 사용할 수 있습니다.

awk -i inplace '/qr/{if (!i++) next}1' test

답변4

일치하는 첫 번째 행만 제거하려면

sed  "0,/qr/{/qr/d;}" file 

-i테스트 후 nline을 입력하세요.

이것은 첫 번째 줄부터 첫 번째 일치까지의 주소만 처리합니다.qr

0,/qr/ 

해당 주소 범위에 포함된 모든 줄을 삭제합니다.qr

{/qr/d;}

관련 정보