첫 번째 항목만 sed로 바꾸는 방법은 무엇입니까?

첫 번째 항목만 sed로 바꾸는 방법은 무엇입니까?

원본 파일

claudio
antonio
claudio
michele

다음과 같은 결과를 얻을 수 있도록 "claudio"의 첫 번째 항목을 "claudia"로 변경하고 싶습니다.

claudia
antonio
claudio
michele

나는 다음을 시도했습니다 :

sed -e '1,/claudio/s/claudio/claudia/' nomi

위 명령은 전역 교체를 수행합니다(모든 "claudio" 항목을 교체합니다). 왜?

답변1

GNU를 사용하는 경우 다음을 sed시도해 보세요.

sed -e '0,/claudio/ s/claudio/claudia/' nomi

sed까지 종료 범위에 대한 정규식 검사를 시작하지 않습니다.뒤쪽에범위를 시작하는 줄입니다.

~에서man sed(POSIX 맨페이지, 강조 광산):

두 개의 주소가 있는 편집 명령은 첫 번째 주소와 일치하는 첫 번째 패턴 공간에서 포함 범위를 선택해야 합니다.다음 패턴 공간두 번째 것과 일치합니다.

하지만 이 주소는 표준이 아니며 다른 구현에서는 지원되지 않는 GNU 확장 0입니다 .sedsed

사용awk

작업 범위는 awk귀하의 기대에 더 부합합니다.

$ awk 'NR==1,/claudio/{sub(/claudio/, "claudia")} 1' nomi
claudia
antonio
claudio
michele

설명하다:

  • NR==1,/claudio/

    이는 라인 1에서 시작하여 첫 번째 항목에서 끝나는 범위입니다 claudio.

  • sub(/claudio/, "claudia")

    이 대체 명령은 범위 내에 있을 때 실행됩니다.

  • 1

    이것은 awk의 인쇄 라인에 대한 비밀스러운 약어입니다.

답변2

GNU의 새 버전은 sed-z옵션을 지원합니다.

일반적으로 sed는 줄 끝 문자(개행 또는 캐리지 리턴)까지 문자열을 읽어서 줄을 읽습니다.
버전 4.2.2의 GNU 버전 sed에는 "NULL" 문자를 대신 사용하는 기능이 추가되었습니다. 이는 레코드 구분 기호로 NULL을 사용하는 파일이 있는 경우 유용합니다. 일부 GNU 유틸리티는 "find . -print0" 또는 "grep -lZ"와 같이 새 줄 대신 NULL을 사용하는 출력을 생성할 수 있습니다.

sed다른 라인에서 작업하려는 경우 이 옵션을 사용할 수 있습니다.

echo 'claudio
antonio
claudio
michele' | sed -z 's/claudio/claudia/'

반품

claudia
antonio
claudio
michele

답변3

요약하다

GNU 구문:

sed '/claudio/{s//claudia/;:p;n;bp}' file

또는 (대체하려는 단어를 한 번만 사용:

sed '/\(claudi\)o/{s//\1a/;:p;n;bp}' file

또는 POSIX 구문을 사용하여:

sed -e '/claudio/{s//claudia/;:p' -e 'n;bp' -e '}' file

모든 sed, 프로세스에 적용 가능오직첫 번째를 찾으면 첫 번째 줄에 claudio있더라도 가능한 한 많은 줄이 필요하며 claudio하나의 정규식 문자열만 사용되므로 더 짧습니다.

세부 사항

변경만한 줄당신은해야합니다선택하다줄이 하나뿐입니다.

1,/claudio/(질문에서) 다음을 사용하여 선택하십시오.

  • 첫 번째 줄부터 시작(무조건)
  • 도착하다다음string 을 포함하는 라인 claudio.
$ cat file
claudio 1
antonio 2
claudio 3
michele 4

$ sed -n '1,/claudio/{p}' file
claudio 1
antonio 2
claudio 3

선택하다어느줄을 포함하려면 claudio다음을 사용하세요.

$ sed -n `/claudio/{p}` file
claudio 1
claudio 3

그리고만 선택첫 번째 claudio파일에서 다음을 사용합니다.

sed -n '/claudio/{p;q}' file
claudio 1

그런 다음 해당 줄에서만 바꿀 수 있습니다.

sed '/claudio/{s/claudio/claudia/;q}' file
claudia 1

이것만 바뀔 거야첫 번째두 개 이상이 있어도 해당 줄에서 정규식 일치가 발생합니다.첫 번째정규식과 일치하는 줄입니다.

물론 /claudio/정규식은 다음과 같이 단순화될 수 있습니다.

$ sed '/claudio/{s//claudia/;q}' file
claudia 1

그런 다음 누락된 유일한 것은 수정되지 않은 다른 모든 줄을 인쇄하는 것입니다.

sed '/claudio/{s//claudia/;:p;n;bp}' file

답변4

awk플래그를 사용하여 교체가 완료되었는지 확인할 수 있습니다. 그렇지 않다면 계속하세요:

$ awk '!f && /claudio/ {$0="claudia"; f=1}1' file
claudia
antonio
claudio
michele

관련 정보