存在多个问题。
cat inputfile.txt
A 254 B 456 C 546
D 548 E 548 F 458
A 244 B 416 C 566
D 148 E 558 F 428
a=(456 416)
b= (469.68 424.32)
for i in ${a[@]};
for j in ${b[@]}; do
sed -i -- "s/${i}/${j}" inputfile.txt
done
一)
您对 b 的分配失败。分配周围没有空间。
b) 替换模式未关闭:
sed -i -- "s/${i}/${j}/" inputfile.txt
c) 现在它应该以不为空的值运行,但这将尝试用 469.68 替换 456,然后用 424.32 替换。这不起作用,因为该值已更改为 469.68。然后它将尝试使用这两个值更改每个 416。
a=(456 416)
b=(469.68 424.32)
for i in ${a[@]};
for j in ${b[@]}; do
sed "s/${i}/${j}/" inputfile.txt
done
您有两个需要同步的对应值,因为您想用第二个替换第一个。所以你必须迭代一次,并且按索引:
max=${#a[@]}
for i in $(seq 0 $((max - 1))); do
sed "s/${a[$i]}/${b[$i]}/" inputfile.txt
done
我从 sed 中删除了用于测试的 -i。
最后一个问题是,可能存在数字冲突,例如将 1456 中的 456 替换为 469.68 或将 416.02 中的 416 替换为 424.32。
为了防止这种情况发生,我们可以在要匹配的数字之前放置一个空格,并在末尾放置一个匹配空格或行尾的边界:
sed "s/ ${a[$i]}\b/ ${b[$i]}/" inputfile.txt
\b 表示法的优点(优于 [$])我们不需要捕获它,将它推回值中,它是不消耗的。
a=(456 416)
b=(469.68 424.32)
max=${#a[@]}
for i in $(seq 0 $((max - 1))); do
sed -i "s/ ${a[$i]}\b/ ${b[$i]}/" inputfile.txt
done
我不知道您的 a 和 b 值的来源 - 也许我的以下推理不适用,但数组中的 as 和 bs 存储似乎不是最佳的。它们必须具有相同的长度,但不能保证相同。你可以测试一下,但是如果一个值丢失了,就很难找出它在哪里,去掉对应的b值。
不结合所有原件和所有替换件,绑定对似乎更好:
a=(456 469.68)
b=(416 424.32)
但这离最终的 sed 表达式不远了,那就是:
a="s/ 456\b/ 469.68/"
b="s/ 416\b/ 424.32/"
现在这有点冗长,但我们将循环保存完整:
sed -i "${a};${b}" inputfile.txt
输入文件只需要读取一次,现在可以在没有-i的情况下完成testet。
如果你碰巧有海量数据,你可以像这样生成一个文件:
s/ 456\b/ 469.68/
s/ 416\b/ 424.32/
并将其命名为 numcorrect.sed,并通过以下方式调用它:
sed -f numcorrect.sed inputfile.txt