我有以下文件: input.txt中
b73_chr10 w22_chr9
w22_chr7 w22_chr10
w22_chr8 w22_chr8
我编写了以下代码(如下所示)来读取第一列和第二列,并将第一列的值替换为output.conf文件中第二列中的值。例如,我想将值更改为b73_chr10 w22_chr9,w22_chr7与w22_chr10,w22_chr8与w22_chr8并继续执行所有值直到结束。
value1=$(echo $line| awk -F\ '{print $1}' input.txt)
value2=$(echo $line| awk -F\ '{print $2}' input.txt)
sed -i '.bak' 's/$value1/$value2/g' output.conf
cat output.conf
output.conf
<rules>
<rule>
condition =between(b73_chr10,w22_chr1)
color = ylgn-9-seq-7
flow=continue
z=9
</rule>
<rule>
condition =between(w22_chr7,w22_chr2)
color = blue
flow=continue
z=10
</rule>
<rule>
condition =between(w22_chr8,w22_chr3)
color = vvdblue
flow=continue
z=11
</rule>
</rules>
我尝试了命令(如上所述),但是它留给我的空白文件。可以指导哪里出错了吗?
答案 0 :(得分:2)
我怀疑sed
本身就是错误的工具。但是,您可以单独使用bash执行的操作:
#!/usr/bin/env bash
# Declare an associative array (requires bash 4)
declare -A repl=()
# Step through our replacement file, recording it to an array.
while read this that; do
repl["$this"]="$that"
done < inp1
# Read the input file, replacing things strings noted in the array.
while read line; do
for string in "${!repl[@]}"; do
line="${line/$string/${repl[$string]}}"
done
echo "$line"
done < circos.conf
这种方法当然过于简单,因此不应逐字使用 - 您要确保只编辑您真正想要编辑的行(验证它们是否匹配)例如/condition =between/
。请注意,因为此解决方案使用关联数组(declare -A ...
),所以它取决于bash版本4.
如果你用awk解决这个问题,同样的基本原则也适用:
#!/usr/bin/awk -f
# Collect the tranlations from the first file.
NR==FNR { repl[$1]=$2; next }
# Step through the input file, replacing as required.
{
for ( string in repl ) {
sub(string, repl[string])
}
}
# And print.
1
你运行它的第一个参数是翻译文件,第二个参数是输入文件:
$ ./thisscript translations.txt circos.conf
答案 1 :(得分:2)
在你阅读更好的解决方案之前,先解释一下你做错了什么 您的脚本的固定版本将是
while read -r line; do
value1=$(echo "$line"| awk -F" " '{print $1}')
value2=$(echo "$line"| awk -F" " '{print $2}')
sed -i "s/$value1/$value2/g" circos.conf
done < input.txt
这里有什么变化?
while read -r line; do ... done < input.txt
"$line"
从未初始化这个解决方案有什么问题?
首先,您必须希望input.txt中的值是sed_friendly(没有斜杠或其他特殊字符)。
当你将它用于大文件时,你将继续循环。 awk
可以处理循环,你应该避免在循环中嵌入awk。
当input.txt受限时,您可能需要类似
的内容sed -i -e 's/b73_chr10/w22_chr9/g' \
-e 's/w22_chr7/w22_chr10/g' \
-e 's/w22_chr8/w22_chr8/g' circos.conf
现在@alvits的评论很有意义。将所有这些sed命令放在sed-command文件中。如果你不能改变input.txt的格式,你可以在脚本中重写它,但是在@Ghoti的解决方案中使用数组会更好。