我正在尝试通过其他数字更改长列表中的数字。例如,
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
我想通过在其上添加一个百分比来改变B的值。例如,我想将第一个数组中的B增加3%,将下一个中的b增加2%,如下所示:
cat inputfile.txt
A 254 B 469.68 C 546
D 548 E 548 F 458
A 244 B 424.32 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
答案 0 :(得分:4)
有很多问题。
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
A) 你对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替换为4169中的469.68或416和424.32。
为了防止这种情况发生,我们可以在匹配的数字前加上一个空格,并在最后匹配空白或行尾的边界:
sed "s/ ${a[$i]}\b/ ${b[$i]}/" inputfile.txt
\ b-notation具有我们不需要抓住它的优势(超过[$]),将其推回到值中,它是非消费的。
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-expression不远,那就是:
a="s/ 456\b/ 469.68/"
b="s/ 416\b/ 424.32/"
现在这个问题有点冗长,但我们保存完整的循环:
sed -i "${a};${b}" inputfile.txt
并且输入文件只需要读取一次,现在可以在没有-i的情况下完成测试。
如果你碰巧有海量数据,你可以生成如下文件:
s/ 456\b/ 469.68/
s/ 416\b/ 424.32/
并将其命名为numcorrect.sed,并通过以下方式调用:
sed -f numcorrect.sed inputfile.txt