Bash while 루프 검색 및 sed를 사용하여 바꾸기

Bash while 루프 검색 및 sed를 사용하여 바꾸기

다음 스크립트에 문제가 있습니다(이 부분이 관련 부분입니다).

#!/bin/bash

OLD=(
"_MAIN1_"
"_MAIN2_"
)

NEW=(
"#111"
"#222"
)

length=${#OLD[*]}

i=0

while (( i < length ))
do
  sed -e "s/${OLD[$i]}/${NEW[$i]}/g" oldfile.txt > newfile.txt

  #sed -e 's/_MAIN1_/#111/g' oldfile.txt > newfile.txt  # this works

  # Another way that does not work
  #sed -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt > newfile.txt

  ((i++))
done

exit 0

내 목표는 파일의 문자열을 바꾸고 새 문자열에 저장하는 것입니다. "이전" 및 "새" 문자열은 배열에 저장됩니다.

나는 많은 것을 시도하고 작은 따옴표와 큰 따옴표를 사용해 보았지만 아무것도 작동하지 않았습니다. 변수를 사용하면 echo루프 내부에서 올바른 문자열을 얻습니다. 명령 에 명시적인 두 문자열이 설정되어 있으면 sed제대로 작동합니다.

문자열 패턴은 예제 배열의 패턴을 따릅니다('new'에는 밑줄 "_"이 포함되고 'old'에는 해시태그 "#"이 포함됨).

Ubuntu 16.04 상자에서 bash를 실행하고 있습니다.

매우 감사합니다!

답변1

모든 대체를 수행하는 스크립트를 만든 sed다음 해당 sed스크립트를 파일에 적용합니다.

for (( i=0; i<${#OLD[@]}; ++i )); do
        printf 's/%s/%s/g\n' "${OLD[$i]}" "${NEW[$i]}"
done >script.sed

sed -f script.sed inputfile >outputfile && mv outptufile inputfile && rm script.sed

이렇게 하면 입력 파일을 구문 분석하는 데 필요한 횟수를 하나로 제한할 수 있습니다.

주어진 데이터에 대해 스크립트 는 OLD다음과 같이 생성됩니다.NEWsed

s/_MAIN1_/#111/g
s/_MAIN2_/#222/g

답변2

작동하지 않는 전체 스크립트를 다음 한 줄로 바꿀 수 있습니다.

sed 's/_MAIN\([12]\)_/#\1\1\1/g' oldfile.txt > newfile.txt

또는 더 읽기 쉽지만 동등하게:

sed 's/_MAIN1_/#111/g;s/_MAIN2_/#222/g' oldfile.txt > newfile.txt

이를 수행하는 방법에는 귀하의 상황에 따라 수십 가지가 있습니다.실제사용 사례(예: 데이터의 출처, 값의 실제 모양, 데이터로 수행하려는 작업 등).

답변3

덕분에라케시 샤르마님의 의견 -ised 명령에서 플래그를 사용하면 이 문제를 해결할 수 있습니다. 루프 전에 원본 파일이 백업됩니다.

cp oldfile.txt oldfile.backup
while (( i < length ))
do
  sed -i -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt
  ((i++))
done

다음번에는 문자열 조작을 위해 Perl을 사용할 것입니다.

편집하다:무한 루프를 방지하기 위해 추가되었습니다 ((i++))(덕분에쿠살라난다님의 댓글).

관련 정보