![如何在 sed 命令中添加“$i”、for 循环?](https://linux22.com/image/14441/%E5%A6%82%E4%BD%95%E5%9C%A8%20sed%20%E5%91%BD%E4%BB%A4%E4%B8%AD%E6%B7%BB%E5%8A%A0%E2%80%9C%24i%E2%80%9D%E3%80%81for%20%E5%BE%AA%E7%8E%AF%EF%BC%9F.png)
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
表达式,阻止 shell 扩展命令替换部分中的变量s///
。您就地更改了原始
1.txt
文件,因此即使 shell 扩展了变量,该模式在第二次循环时也不会匹配(因为文件已被前一次迭代修改)。您
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.20d0
for )。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