2

如何根据第一列加入两个文件并保留第二个文件的顺序.. 

文件 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 的行数/ID 比文件 2 多。ID文件 2 中的所有 s 都在文件 1 中,但并非ID文件 1 中的所有 s 都在文件 2 中

4

3 回答 3

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
于 2012-11-23T11:23:29.827 回答
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,不会按任何列/标准进行排序。

于 2012-11-23T11:26:51.803 回答
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);

?>

(请注意,我没有检查这个,我只是把这个写下来。它是一个起点,而不是即用型)

于 2012-11-23T11:00:51.417 回答