这里有2个文件,我想从fileB中的值(如果存在)中替换fileA中的值。
这个想法是逐行处理fileA并检查“ gene_id”值(第3列)是否在fileB的#1列中。
在fileA的第一行中,该值在fileB中找到。因此,我们将fileA“ id1.2”(第3列)中的值替换为fileB“ ND1”(第3列)中的值。 在fileA的第二行中,在fileB中找不到该值。所以它什么也没做。
困难还在于,文件A和文件B之间的模式不完全相同,但是“ .2”之前的整个部分必须相同(例如,文件B中的id1与文件A中的“ id1.2”)。 / p>
原始文件:
> cat fileA.txt
chr1 gene_id "id1.2";
chr1 gene_id "id2.2";
> cat fileB.txt
id1 protein_coding ND1 MT
想要的文件(从文件B的第3列中提取值,如果有匹配项,则将其放在文件A的第3列中):
> cat fileA.txt
chr1 gene_id "ND1";
chr1 gene_id "id2.2";
我尝试了一些受此post启发的内容,但是它没有用(我不确定我是不是第一次使用这种语法,所以我确实了解awk行的含义):
awk -F ' ' 'NR==FNR{a[$1]=$3;next}{$3=a[$3];}1' fileB.txt fileA.txt
任何帮助都将受到欢迎。
答案 0 :(得分:2)
请您仅根据示例(根据实际输入文件相应更改列号)尝试以下操作。
awk -v s1="\"" '
FNR==NR{
a[$1]=$3
next
}
{
val=$3
gsub(/\"|;|\..*/,"",val)
}
(val in a){
$3=s1 a[val] s1";"
}
1
' fileb filea |
column -t
答案 1 :(得分:0)
几个月后,我想出了另一个选择,对于那些不习惯awk的人来说,这更容易理解。如果可以帮助某人,我在这里分享:
BEGIN {
FS="\t";
while (getline < fileB ){
geneTable[$1] = $3
}
close(fileB)
}
{
split($0, geneID, "gene_id \"")
split(geneID[2], geneID, ".")
if (geneID[1] in geneTable){
$2 = "gene_id \"" geneTable[geneID[1]] "\";"
}
print $0
}
最好的方法是将此命令存储在一个外部文件中,在这里我们称之为cmd.awk
。要运行脚本:
awk -v fileB="fileB.txt" -f cmd.awk fileA.txt | column -t
BEGIN
部分将读取fileB.txt并将结果存储在数组geneTable
中。split
部分用于获取fileA.txt中“ gene_id”之后的值。if
(=在fileB.txt中找到)中,geneTable
部分将替换fileA.txt中的值