在Linux上join两个文件

我有两个文件; 我想join他们。

$cat t1 1 1.2 2 2.2 $cat t2 1 2 1 

我想要下面的输出

 $cat joind.txt 1 1.2 2 2.2 1 1.2 

但是当我使用join命令时,第三行不会出现在输出中。

Solutions Collecting From Web of "在Linux上join两个文件"

join要求这两个文件进行排序。 如果你先排序他们,你会得到你所有的输出

 $ sort t1 > t1.sorted $ sort t2 > t2.sorted $ join -j1 -o 1.1,1.2 t1.sorted t2.sorted 1 1.2 1 1.2 2 2.2 

没有这种排序:

 $ join -j1 -o 1.1,1.2 t1 t2 1 1.2 2 2.2 

这假定您的输入顺序不需要保留; 如果他们这样做,你将需要一个像其他答案已经提供的自定义脚本。

一个简单的awk就足够了:

 awk 'FNR==NR{a[$1]=$2;next} {print $1, a[$1]}' t1 t2 1 1.2 2 2.2 1 1.2 

分手:

 NR == FNR { # While processing the first file a[$1] = $2 # store the second field by the first next # move to next record in 1st file } { # while processing the second file print $1, a[$1] # print $1 and the remembered # value from the first file. } 

如果我明白你想匹配t1的第一列和t1的值。 所以t1是一个dictionnary, t2是想要的键。

如果是这样,你可以使用这个:

 $ cat t2 | xargs -n1 -I{} grep -P "^\Q{}\E\s+" t1 

它是如何工作的?

xargs会为t2每个条目-n1执行命令grep-I{}允许我把价值放在我想要的地方。

然后,我使用正则表达式执行grep ,使其与字典中的所需值相匹配。

 ^ # Any line that begin with \Q # Quote the value (in case we have special chars inside it) {} # The corresponding value matched by xargs \E # End of quoting \s+ # Followed by one or more spaces (alternatively we can use `\b`) .* # Followed by anything (optional) t1 # Inside the file `t1` 

或者,你可以玩Perl的:)

 cat t2 | perl -e '$_ = qx{cat $ARGV[0]}; \ $t1{$1} = $2 while(/^(\w+)\s+(.*)/gm); \ print "$t1{$_}\n" for (split "\n", do{local $/, <STDIN>})' t1 

像下面这样做:

 $ while IFS= read -r line; do grep -m 1 "^$line" t1; done <t2 1 1.2 2 2.2 1 1.2 

你可以试试AWK

awk 'NR==FNR{a[$1]=$2}NR>FNR{print $1,a[$1]}' t1 t2