第一次在这里发帖,我搜索了很长时间,但没有找到一个我能理解的、足以解决我的问题的线索。
我的脚本中有一个循环,它通过 cut -d 分隔符生成某些变量,我想使用这些变量作为 sed 的输入,以便每次迭代都以不同的方式更改文件。我当前的脚本是:
我当前的脚本如下所示:
for input in $(tail -n 3 filea)
do
a="$(echo $input | cut -d "," -f 1)"
b="$(echo $input | cut -d "," -f 2)"
c="$(echo $input | cut -d "," -f 3)"
echo $a
echo $b
echo $c
tail -n 1 fileb | sed 's,'$a','$c',2'
done
输出为:
K
26
T
KTTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
P
27
E
KKTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
S
31
P
KKTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
例如,如果位置 31 的字符串是 P,则应该将其替换为 S。
我当前的状态是,我已将变量 a 和 c 正确传输到 sed 命令中,并且相应的字符串被替换,但将其更改为会sed 's,'$a','$c','$b''
停止任何替换,并且会提示 fileb 的本机(最后一行)。
我知道提出一个好问题是另一个话题,但我希望有人可以帮助我理解这里的文字,这样我就可以继续学习编程,因为我经常会遇到这样的错误。
答案1
笔记:
- 不要用于
for
读取文件的行 - 使用
IFS
和read
使用分隔符来分割线 - 更加严格地引用变量。
鉴于:
$ cat filea
K,26,T
P,27,E
S,31,P
$ cat fileb
-------------------------TE---P---
然后
tail -n 3 filea | while IFS=, read -r replacement position character; do
printf -v regex '^(.{%d})%s' $((position - 1)) "$character"
printf -v repl '\\1%s' "$replacement"
echo "$regex"
echo "$repl"
tail -n 1 fileb
tail -n 1 fileb | sed -E "s/$regex/$repl/"
done
输出:
^(.{25})T
\1K
-------------------------TE---P---
-------------------------KE---P---
^(.{26})E
\1P
-------------------------TE---P---
-------------------------TP---P---
^(.{30})P
\1S
-------------------------TE---P---
-------------------------TE---S---
但是,bash 可以在没有 sed 的情况下做到这一点,使用${var:offset:length}
以下形式参数扩展:
tail -n 3 filea | while IFS=, read -r replacement position character; do
echo "$replacement $position $character"
line=$(tail -n 1 fileb)
echo "$line"
if [[ "${line:position - 1:1}" == "$character" ]]; then
line=${line:0:position - 1}${replacement}${line:position}
fi
echo "$line"
done
输出
K 26 T
-------------------------TE---P---
-------------------------KE---P---
P 27 E
-------------------------TE---P---
-------------------------TP---P---
S 31 P
-------------------------TE---P---
-------------------------TE---S---