sed를 사용하여 여러 번 나타나는 단어를 목록의 단어로 바꿉니다.

sed를 사용하여 여러 번 나타나는 단어를 목록의 단어로 바꿉니다.

여러 번 발생하는 줄 목록이 포함된 파일이 있습니다.

output = filename
output = filename
output = filename
output = filename

filename또한 다음 순서로 항목을 바꾸는 데 사용하려는 txt 파일에 파일 이름의 시간순 목록이 있습니다.

2d_slv_Nx.19800111.SUB.nc
2d_slv_Nx.19800213.SUB.nc
2d_slv_Nx.19800322.SUB.nc
2d_slv_Nx.19800510.SUB.nc

나는 다음과 같은 출력을 원한다

output = 2d_slv_Nx.19800111.SUB.nc
output = 2d_slv_Nx.19800213.SUB.nc
output = 2d_slv_Nx.19800322.SUB.nc
output = 2d_slv_Nx.19800510.SUB.nc

답변1

   $ cat tmplate.sh 
    output = filename

    output = filename

    output = filename

    output = filename

    $ cat mkrepl.sh 

   while read fname
   do
     sed -i -e "0,/filename/s/filename/$fname/" tmplate.sh
   done < tmplate.sh
   $ 

Bash 스크립트: tmplate.sh에서 줄을 읽고 각 줄을 변수로 추출한 fname다음 sedbash 대체를 사용하여 실행합니다.

사용 sed,

  • -i 인라인 편집
  • -e 표현:

사용 범위

  • 0을 /filename/의 라인으로 설정합니다(라인 0에서 시작하면 첫 번째 대체 후 sed가 중지됩니다).
  • filename다음 으로 교체$fname

답변2

이것은 해결하기 쉽습니다 awk.

sed루프를 사용하는 것과 비교하여 이 솔루션은 입력 파일을 읽고 출력 파일을 한 번만 쓰고 하나의 프로세스만 사용합니다. 파일 이름 목록이 길수록 더 빠릅니다.


파일 이름을 포함하는 파일이 호출 filenames되고 수정할 줄이 포함된 입력이 호출된다고 가정하면 input다음을 사용할 수 있습니다.

awk 'NR == FNR {name[i++]=$0;next} /^output = filename$/ { $3 = name[j++]; } 1' filenames input > output

설명하다:

이 조건은 NR == FNR첫 번째 파일에만 적용됩니다. 행의 추가 처리를 건너뛰고 행 name[i++]=$0;을 배열에 저장합니다 . (도 가능 .)namenextname[NR]=$0;next

/^output = filename$/교체할 행과 일치하며 $3 = name[j++];세 번째 필드를 배열의 이름으로 바꿉니다. 0부터 다시 계산을 시작하는 j대신 새 인덱스를 사용했습니다 .i

1암시적 기본 동작이 포함된 "항상 참" 조건입니다.print

노트:수정하려는 줄이 실제 입력과 다르게 보이는 경우 스크립트가 작동하지 않을 수 있습니다. filenames파일에 교체할 ​​라인 수보다 적은 데이터가 포함되어 있는 경우 에는 오류 처리가 발생하지 않습니다.

관련 정보