如何在 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表达式,阻止 shell 扩展命令替换部分中的变量s///

  2. 您就地更改了原始1.txt文件,因此即使 shell 扩展了变量,该模式在第二次循环时也不会匹配(因为文件已被前一次迭代修改)。

  3. 1.txt在第一次迭代中将文件移走,这将使sed命令失败,并在后续每次迭代中出现“没有这样的文件或目录”错误。

解决这三个问题:

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

请注意,我还要确保图案中的点与文字点而不是任何字符(.如果它没有转义为\.或用作 ,则会执行此操作[.])。我仍然在表达式中使用单引号sed,但我暂时打破它,从 shell 变量中引入双引号值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,它也能正确插入数字(例如,创建0.020d0而不是0.20d0for )。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

引号'使得变量被字面解释为而$i不是 30、31、32 等。

我做了以下更改,将整个 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

相关内容