如何基于第一列连接两个文件并保留第二个文件中的顺序..
文件1:
ID1 123
ID2 234
ID3 232
ID4 344
ID5 345
ID6 867
文件2
ID2 A C
ID3 G T
ID1 C T
ID4 A C
...
因此合并后的文件应如下所示:
ID2 234 A C
ID3 232 G T
ID1 123 C T
ID4 344 A C
...
IDs
是第一列的值(存在于两个文件中)。文件1具有比文件2更多的行/ ID。
文件2中的所有ID
都在文件1中,但文件1中的所有ID
都不在文件2中
答案 0 :(得分:4)
这是使用awk
的一种方式:
awk 'FNR==NR { a[$1]=$2; next } $1 in a { print $1, a[$1], $2, $3 }' file1 file2
结果:
ID2 234 A C
ID3 232 G T
ID1 123 C T
ID4 344 A C
答案 1 :(得分:2)
使用join
:
$ join file1.txt file2.txt
ID1 123 C T
ID2 234 A C
ID3 232 G T
ID4 344 A C
注意:文件需要先排序,不保留file2.txt的顺序,但如果您不关心这个最干净的方式。
首先对文件进行预排序:sort file1.txt -o file1.txt; sort file2.txt -o file2.txt
加入:join file1.txt file2.txt
一般情况下,您可以join file1.txt file.txt | sort
对某些条件进行排序,但在这种情况下,file2.txt
不会按任何列/条件排序。
答案 2 :(得分:0)
您逐行读取这两个文件,并通过正则表达式提取行标记。提取的标记存储在关联数组中,使用第一个标记作为关键字。在第二步中,您可以循环遍历所有可用键,并根据存储在数组中的值构造输出行。
php中的示例实现,仅用于演示目的。因此,没有完成错误检查,可能必须根据您的需要调整模式。显然可以在所有其他语言中完成相同的操作。我刚刚选择了php,因为它很容易阅读:
<?php
$input_file[1]=fopen('/path/input1.list','r');
$input_file[2]=fopen('/path/input2.list','r');
# read input files line by line
foreach ($input_file as $input){
while (!feof($input)){
$tokens=array();
preg_match('/^(ID[0-9]+) (.+)$/',trim(fread($input)),$tokens);
$list[$i][$tokens[1]]=$tokens[2];
}
}
# construct output lines:
$output_file=fopen('/path/output.list','w');
foreach ($list[1] as $key=>$val){
$line=sprintf("%s %s%s\n", $key, $val,
array_key_exists($key,$list[2])?' '.$list[2][$key]:'' );
fwrite($output_file,$line);
}
# some house keeping
fclose($input_file[1]);
fclose($input_file[2]);
fclose($output_file);
?>
(请注意,我没有检查过这个,我只是把它写下来。这是一个起点,不是随时可用的)