sed 명령에 "$i" 및 for 루프를 추가하는 방법은 무엇입니까?

sed 명령에 "$i" 및 for 루프를 추가하는 방법은 무엇입니까?
for (( i=30; i<=44; i++))
do
sed -i '28s/0.340d0/0."$i"0d0/' 1.txt 
mv 1.txt "$i".txt     
done

그러나 실행하면 작동하지 않습니다. sed 명령 "$i" 루프 내에서는 작동하지 않습니다. 도와주세요. 1.txt 파일의 28번째 줄에 있는 숫자 0.340do가 복사된 파일의 0.30d0에서 0.440d0으로 대체되기를 원합니다.

답변1

코드에 세 가지 문제가 있습니다.

  1. 작은따옴표로 묶인 문자열을 sed표현식으로 사용하여 쉘이 명령의 대체 섹션에서 변수를 확장하는 것을 방지합니다 s///.

  2. 원본 1.txt파일을 그 자리에서 변경하므로 쉘이 변수를 확장하더라도 루프를 통해 두 번째로 패턴이 일치하지 않습니다(이전 반복에서 파일이 수정되었기 때문입니다).

  3. 1.txt첫 번째 반복에서 파일을 이동하면 각 sed후속 반복에서 "해당 파일 또는 디렉터리가 없습니다"라는 오류와 함께 명령이 실패하게 됩니다.

다음 세 가지 문제를 해결하세요.

for number in {30..44}; do
    sed '28 s/0\.340d0/0.'"$number"'0d0/' 1.txt >"$number.txt"
done

또한 패턴의 포인트가 정렬되었는지 확인합니다.단어문자 대신 점을 사용합니다( .이스케이프되거나 사용되지 않는 경우 \.수행됩니다 [.]). 표현식에는 여전히 작은따옴표를 사용하고 있지만 sed일시적으로 이를 깨고 쉘 변수에서 큰따옴표 값을 도입하고 있습니다 number.

명령의 결과는 변수를 sed사용하여 number이름이 지정된 파일에 기록됩니다.

문자열로 시작한다는 사실을 사용할 수도 있습니다 rmin=(이것이 다음과 같다고 가정).오직이 문자열로 시작하는 줄):

for number in {30..44}; do
    sed 's/^rmin=.*/rmin=0.'"$number"'0d0/' 1.txt >"$number.txt"
done

다음을 사용하면 동일한 작업을 더 간결하게 수행할 수 있습니다 awk.

for number in {30..44}; do
    awk -v num="$number" 'FNR == 28 { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done

이 방법의 장점은 숫자가 10보다 작더라도 숫자를 올바르게 삽입한다는 것입니다(예: for 0.020d0대신 create 0.20d0).2

또는 rmin=줄 시작 부분에서 일치시킵니다.

for number in {30..44}; do
    awk -v num="$number" '/^rmin=/ { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done

답변2

따옴표 로 인해 변수는 30, 31, 32 등이 '아닌 문자 그대로 해석됩니다 .$i

전체 sed 표현식을 따옴표로 묶기 위해 다음과 같이 변경했습니다 ".

for (( i=30; i<=44; i++))
do
sed "s/0.340d0/0.${i}0d0/g" 1.txt > temp.txt
cp temp.txt "$i".txt     
done

관련 정보