使用 bash 中的参考列表替换 newick 文件的提示
Replace tip of newick file using reference list in bash
我有一组包含基因 ID 的 newick 格式文件:
((gene1:1,gene2:1)100:1,gene3:1)100;
((gene4:1,gene5:1)100:1,gene6:1)100;
我有一个基因 ID 和物种名称之间的等价列表:
speciesA=(gene1,gene4)
speciesB=(gene2,gene5)
speciesC=(gene3,gene6)
我想获得以下输出:
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
知道我该如何继续吗?理想情况下 bash 会很棒 :)
input.txt
((gene1:1,gene2:1)100:1,gene3:1)100;
((gene4:1,gene5:1)100:1,gene6:1)100;
equivs.txt
speciesA=(gene1,gene4)
speciesB=(gene2,gene5)
speciesC=(gene3,gene6)
convert.sh
#!/bin/bash
function replace() {
output=
for line in $(cat equivs.txt) #this will fail if there is whitespace in your lines!
do
#gets the replacement string
rep=$(echo $line | cut -d'=' -f1)
#create a regex of all the possible matches we want to replace with $rep
targets=$(echo $line | cut -d'(' -f2- | cut -d')' -f1)
regex="($(echo $targets | sed -r 's/,/|/g'))"
#do the replacements
output=$(echo $output | sed -r "s/${regex}/${rep}/g")
done
echo $output
}
#step through the input, file calling the above function on each line.
#assuming all lines are formatted like the example!
for line in $(cat input.txt)
do
replace $line
done
输出:
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
这是一个 awk 单行代码,可以满足您的需求:
$ awk -F'[()=,]+' 'NR==FNR{a[]=a[]=;next}{for(i in a)gsub(i,a[i])}1' species gene
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
浏览包含物种和基因之间映射的文件,将它们保存为数组 a
中的键值对。 NR==FNR
以传递给 awk 的第一个文件为目标,因为总行号 NR
等于当前文件中的行号 FNR
。 next
跳过任何进一步的说明。浏览第二个文件并进行替换。
我有一组包含基因 ID 的 newick 格式文件:
((gene1:1,gene2:1)100:1,gene3:1)100;
((gene4:1,gene5:1)100:1,gene6:1)100;
我有一个基因 ID 和物种名称之间的等价列表:
speciesA=(gene1,gene4)
speciesB=(gene2,gene5)
speciesC=(gene3,gene6)
我想获得以下输出:
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
知道我该如何继续吗?理想情况下 bash 会很棒 :)
input.txt
((gene1:1,gene2:1)100:1,gene3:1)100;
((gene4:1,gene5:1)100:1,gene6:1)100;
equivs.txt
speciesA=(gene1,gene4)
speciesB=(gene2,gene5)
speciesC=(gene3,gene6)
convert.sh
#!/bin/bash
function replace() {
output=
for line in $(cat equivs.txt) #this will fail if there is whitespace in your lines!
do
#gets the replacement string
rep=$(echo $line | cut -d'=' -f1)
#create a regex of all the possible matches we want to replace with $rep
targets=$(echo $line | cut -d'(' -f2- | cut -d')' -f1)
regex="($(echo $targets | sed -r 's/,/|/g'))"
#do the replacements
output=$(echo $output | sed -r "s/${regex}/${rep}/g")
done
echo $output
}
#step through the input, file calling the above function on each line.
#assuming all lines are formatted like the example!
for line in $(cat input.txt)
do
replace $line
done
输出:
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
这是一个 awk 单行代码,可以满足您的需求:
$ awk -F'[()=,]+' 'NR==FNR{a[]=a[]=;next}{for(i in a)gsub(i,a[i])}1' species gene
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
((speciesA:1,speciesB:1)100:1,speciesC:1)100;
浏览包含物种和基因之间映射的文件,将它们保存为数组 a
中的键值对。 NR==FNR
以传递给 awk 的第一个文件为目标,因为总行号 NR
等于当前文件中的行号 FNR
。 next
跳过任何进一步的说明。浏览第二个文件并进行替换。