按第一列比较两个文件。如果匹配则保留行

按第一列比较两个文件。如果匹配则保留行

你好,

我有两个 csv 文件:File1(约 18800 行):

            p1  p10 p16 p19 p25 p3  p5  p6  p8  p9
    A3      567 0   3   0   18  17  8   4   6   7
    B23     490 7   6   2   23  26  20  14  12  29
    A56     737 1   4   1   6   4   1   4   8   5
    Z56     145 6   4   0   11  17  5   9   22  11
    D89     68  0   0   34  4   0   0   0   0   0
    A12     46  0   0   8   0   0   0   0   0   0
    A15     72  0   0   8   0   1   0   0   0   0
    D4      40  0   0   0   0   1   5   18  0   0
    Z6       7  0   1   0   1   1   10  1   2   0
    X3      49  0   0   125 0   0   0   0   0   0

文件2(约400行)

        name    tax price class order 

        B23      kat 35    2      1
        Z56      mat 26    3      2
        D4       kat 26    4      1

现在我想按第一列比较这两个文件。如果第二个文件中的值存在于第一个文件中,我想保留整个匹配行。下面是输出示例:

            p1  p10 p16 p19 p25 p3  p5  p6  p8  p9
    B23     490 7   6   2   23  26  20  14  12  29
    Z56     145 6   4   0   11  17  5   9   22  11
    D4      40  0   0   0   0   1   5   18  0   0

编辑:File1猫

    "","p1","p10","p16","p19","p25","p3","p5","p6","p8","p9"
"p1_1_length_2509_cov_19.337112",567,0,3,0,18,17,8,4,6,7
"p1_10_length_1072_cov_559.052910",4900,7,6,2,23,26,20,14,12,29
"p1_11_length_1032_cov_5800.211050",73784,1,4,1,6,4,1,4,8,5
"p1_12_length_1022_cov_10156.344134",145873,6,4,0,11,17,5,9,22,11
"p1_13_length_946_cov_7.164835",77,17936,61876,5257,6085,196,8383,24956,4656,14687
"p1_14_length_921_cov_15.662469",68,0,0,34,4,0,0,0,0,0
"p1_16_length_800_cov_7.126300",46,0,0,8,0,0,0,0,0,0
"p1_17_length_758_cov_12.328051",72,0,0,8,0,1,0,0,0,0
"p1_19_length_722_cov_5.621849",40,0,0,0,0,1,5,18,0,0

文件2猫:

name,superkingdom,phylum,class,order,family,genus,species
p10_1003_length_529_cov_12.940299,Viruses,,,,Poxviridae,Alphaentomopoxvirus,Anomala cuprea entomopoxvirus
p10_1021_length_525_cov_6.801508,Viruses,,,Herpesvirales,Alloherpesviridae,Batrachovirus,Ranid herpesvirus 1
p10_1047_length_521_cov_4.852792,Viruses,,,,,,Hudisavirus sp.
p10_1152_length_501_cov_22.430481,Viruses,,,,Mimiviridae,Cafeteriavirus,Cafeteria roenbergensis virus
p10_139_length_1152_cov_892.463415,Viruses,,,,,,Hudisavirus sp.
p10_149_length_1130_cov_7.540379,Viruses,,,Picornavirales,Picornaviridae,Enterovirus,Enterovirus C

答案1

您想要提取第一个文件中第一列与第二个文件中的列相对应的所有行。

由于第一个文件似乎只在其第一列中包含文本(其余的是数字),因此我们可以简单地使用grep它。

bash或任何其他理解进程替换的 shell 中,这将是一个问题

grep -F -f <( awk -F, 'NR > 1 { print $1 }' <file2 ) file1 >newfile

在其他 shell 中,您首先将命令的输出写入awk临时文件,然后将其与grep -f.

awk生成类似的输出

p10_1003_length_529_cov_12.940299
p10_1021_length_525_cov_6.801508
p10_1047_length_521_cov_4.852792
p10_1152_length_501_cov_22.430481
p10_139_length_1152_cov_892.463415
p10_149_length_1130_cov_7.540379

并且grep将使用这些作为固定字符串模式来匹配第一个文件中的每一行。

您也可以完成这一切awk,其中包括首先读取第二个文件的第一列,作为关联数组中的键,然后根据这些键测试第一个文件的第一列:

awk -F, 'NR==FNR && FNR>1 { keys[sprintf("\"%s\"", $1)] }
         NR!=FNR && FNR>1 && ($1 in keys)' file2 file1

奇怪的sprintf()是,因为第一列file1是双引号的。它只是向从 读取的数据添加双引号file2

如果我们从FNR>1.NR==FNRfile2

答案2

这是一项最适合编程语言而不是脚本语言的工作,因为您不仅仅使用一个流。一种基本算法是:

  1. 逐行读取第一个文件。构造所有第一个元素的列表。 (根据您使用的语言,哈希或字典可能是最有效的。)
  2. 逐行读取第二个文件。如果第一个元素存在于列表中的 #1 中,请将其保存到输出文件中。

相关内容