如何从Linux中的两个文件中选择匹配的数据?

时间:2019-02-25 14:43:29

标签: awk

我有2个带有基因列表的文件(两个文件的其他列都提供了基因列表上的不同信息),我正在寻找识别出现在两个文件中的基因,并从两个文件中提取匹配基因的信息以放入其中一个新文件。

例如,数据如下所示:

File 1
Gene   P value
ACT      0.1
BRCA     0.3
AGT      0.004
UMOD     0.05

File 2
Gene    Tissue
MTHFR   Heart
UMOD.1  Kidney
TP53    Lung
ACT     Lung

我正在尝试获得这样的输出:

Gene   P value    Tissue
UMOD   0.05       Kidney
ACT    0.1        Lung

我遇到的一个问题是,一个文件具有匹配的基因,但是具有额外的数字(例如UMOD与UMOD.1),因此即使它们是相同的基因,其基因名称也不完全相同。

到目前为止,我已经尝试了哪些匹配基因:

cat file1.txt|grep -f file2.txt > temp.txt

但是临时文件为空,我不确定为什么这没有用,或者怎么做才能达到我的输出,任何帮助将不胜感激。

我也尝试过编写类似的内容(尽管我知道这全都错了,但是我无法找到从另一个文件中选择列的语法,我正在学习awk):

awk 'BEGIN{FS=OFS="\t"} FNR==1{print;next} {if($1==file2.txt $1) print printf $i""FS; print ""}'  file1txt > temp.txt

3 个答案:

答案 0 :(得分:4)

请您尝试以下。

awk '{sub(/\.[0-9]+$/,"",$1)} FNR==NR{a[$1]=$1 OFS $2;next} $1 in a{print a[$1],$NF}'  file1  file2

每个OP可能在Input_file1中有很多字段,OP可能需要很少的字段,所以我假设让我们说,假设OP在Input_file1中有15个字段,如果是这种情况,则需要14个字段,然后是14个可能会有帮助。(因为没有样品,所以没有测试它,但是应该可以)

awk '{sub(/\.[0-9]+$/,"",$1)} FNR==NR{$15="";sub(/[[:space:]]+$/,"");a[$1]=$0;next} $1 in a{print a[$1],$NF}'  file1  file2

答案 1 :(得分:2)

另一个awk(与@ RavinderSingh13(++)完全相同,但使用split并以相反的文件顺序在标头输出中捕获P value而不定义FS=OFS="\t"):

$ awk '{
    split($1,k,".")         # split $1 on . and store first part to k[1]
}
NR==FNR {
    a[k[1]]=$2              # hash $2 of file2 in a hash, k[1] as key
    next
}
k[1] in a {                 # if k[1] from file1 is found in a hash
    print $0 "\t" a[k[1]]   # output tab-separated
}' file2 file1              # file order reversed 

输出:

Gene    P value Tissue
ACT     0.1     Lung
UMOD    0.05    Kidney

编辑:

文件的字段多于OP中的字段:

$ cat file1
Gene    P value field13
ACT     0.1     val11
BRCA    0.3     val12
AGT     0.004   val13
UMOD    0.05    val14
$ cat file2
Gene    Tissue  field23
MTHFR   Heart   val21
UMOD.1  Kidney  val22
TP53    Lung    val23
ACT     Lung    val24

糟糕:

$ awk 'BEGIN {
    FS=OFS="\t"             # This solution requires field separators set
}
{
    split($1,k,".")         # split $1 on . and store first part (the key) to k[1]
}
NR==FNR {
    $1=""                   # remove unneeded key field from $0
    a[k[1]]=$0              # hash $0 of file2 in a hash, k[1] as key
    next
}
k[1] in a {                 # if k[1] from file1 is found in a hash
    print $0 a[k[1]]        # output tab-separated
}' file2 file1              # file order reversed

输出:

Gene    P value field13 Tissue  field23
ACT     0.1     val11   Lung    val24
UMOD    0.05    val14   Kidney  val22

答案 2 :(得分:1)

您可以使用join进行此操作。以下示例将忽略基因名称中的.1,并且不假定任何标头,例如:

join <(sort file1) <(sort file2)

输出:

ACT 0.1 Lung
UMOD 0.05 Kidney