sed 또는 awk: 문자열의 n번째 항목만 교체

sed 또는 awk: 문자열의 n번째 항목만 교체

다음을 취하는 sed(또는 또는 둘 다) 를 작성하는 방법 :awk

echo '1 aa 2 2 3 bb 5 bb 2 5' | sed/awk ...

그리고 n번째 문자열만 바꾸시겠습니까? 예를 들어 세 번째 등장인가 2, 두 번째 등장인가 bb?

따라서 예상되는 출력은 다음과 같습니다(예: 두 번째 항목을 교체하는 경우) bb.replaced

1 aa 2 2 3 bb 5 replaced 2 5

입력 문자열, 대체 문자열은 n임의의 입력이 될 수 있습니다.

답변1

sed두 번째 발생을 변경하는 데 사용됩니다 .bb

$ sed 's/bb/new-bb/2' file
1 aa 2 2 3 bb 5 new-bb 2 5

또는 2의 세 번째 발생을 변경하십시오.

$ sed 's/2/12/3' file
1 aa 2 2 3 bb 5 bb 12 5

답변2

한 줄에서 n번째 발생 위치를 변경하려면 sed구문은 다음 s/pattern/replacement/3과 같습니다.@HatLess가 이미 시연했습니다..

전체 입력에서 n번째perl 발생을 변경하려면 다음을 사용할 수 있습니다.

perl -pse 'if($n>0) {s{pattern}{--$n ? $& : "replacement"}ge}' -- -n=3

답변3

함께 awk할 수 있는 일:

awk -v str='bb' -v pos=2 -v rplc='newBB' '
 {
   strPos=0
   for(i=1; i<=NF; i++)
       if($i==str && (++strPos==pos) ) { $i=rplc; break }
 }1' infile

산출:

1 aa 2 2 3 bb 5 newBB 2 5

참고: 위의 내용은 필드 구분 기호로 단 하나의 문자만 가정합니다(기본값: 공백 또는 탭). 그렇지 않으면 연속된 필드 구분 기호가 하나로 압축되거나 awk가 각 단일 필드 구분 기호와 별도로 일치하도록 강제할 수 있습니다(따라서 FS는 정규 표현식으로 강제해야 함). 무늬):

awk -F'[\t]' -v OFS='\t' -v str='bb' -v pos=2 -v rplc='newBB' '
 {
   strPos=0
   for(i=1; i<=NF; i++)
      if($i==str && (++strPos==pos) ) { $i=rplc; break }
 }1' infile

참고: \t필드 구분 기호가 공백 문자인 경우 공백 문자로 변경하세요.


전체 입력에서 n번째 항목을 변경하려면 (그러나 필드 구분 기호는 탭이라고 가정합니다):

awk -F'[\t]' -v OFS='\t' -v str='bb' -v pos=2 -v rplc='newBB' '
 strPos!=2{
            for(i=1; i<=NF; i++)
                if($i==str && (++strPos==pos) ) { $i=rplc; break }
 }1' infile

답변4

하나의 명령으로 두 작업을 모두 수행 할 수 있습니다 sed.

echo "1 aa 2 2 3 bb 5 bb 2 5"|sed -e "s/2/kop/3" -e "s/bb/pp/2"

2이 명령은 세 번째 발생 항목을 with 로 kop, 두 번째 발생 항목을 bbwith 로 대체합니다 pp.

관련 정보