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
코드에 세 가지 문제가 있습니다.
작은따옴표로 묶인 문자열을
sed
표현식으로 사용하여 쉘이 명령의 대체 섹션에서 변수를 확장하는 것을 방지합니다s///
.원본
1.txt
파일을 그 자리에서 변경하므로 쉘이 변수를 확장하더라도 루프를 통해 두 번째로 패턴이 일치하지 않습니다(이전 반복에서 파일이 수정되었기 때문입니다).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