你好,
我有两个 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==FNR
file2
答案2
这是一项最适合编程语言而不是脚本语言的工作,因为您不仅仅使用一个流。一种基本算法是:
- 逐行读取第一个文件。构造所有第一个元素的列表。 (根据您使用的语言,哈希或字典可能是最有效的。)
- 逐行读取第二个文件。如果第一个元素存在于列表中的 #1 中,请将其保存到输出文件中。