如果使用awk / sed替换文件A中的值,则替换文件A中的值

时间:2019-09-09 16:25:00

标签: bash awk sed

这里有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

任何帮助都将受到欢迎。

2 个答案:

答案 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中的值