使用公共列合并文件

我有两个文件,我想创建一个包含所有信息的第三个文件。

档案1:

a 111 b 222 c 333 d 666 e 777 

文件2:

 111 x1 222 x2 333 x3 444 x4 555 x5 666 x6 777 x7 888 x8 

我想将它们组合如下:

 111 x1 a 222 x2 b 333 x3 c 444 x4 0 555 x5 0 666 x6 d 777 x7 e 888 x8 0 

注意:

文件1的第二列是文件2的第一列的子集

如果文件按样本中的顺序排序,则join命令几乎可以满足您的需要:

 join -12 -a2 file1 file2 -o2.1,2.2,1.1 

你只需要在没有匹配的行中添加零。 您可以使用-e开关:

 join -12 -a2 file1 file2 -o2.1,2.2,1.1 -e0 

使用join:

 join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1 

join命令连接两个共享公共数据字段的文件的行。 在这种情况下:使用file2的字段1( -1 1 )和file1的字段2( -2 2 )加入file2和file1。

输出将是:“连接字段,file2的字段2,file1的字段1”( – -o'0,1.2,2.1' ),如果有丢失的字段放0( -e0

如果两个文件中的一个有更多记录,则添加它们(在本例中为file2)( – -a1

请参阅命令join的联机帮助页

有点awk魔术:

 awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \ printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \ file1 file2 

要么

 awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; print $1,$2,a[$1]}' file1 file2 

产量

 111 x1 a 222 x2 b 333 x3 c 444 x4 0 555 x5 0 666 x6 d 777 x7 e 888 x8 0 

说明

  • FNR==NR{a[$2]=$1;next}

    运行file1FNR==NR )并创建键值结构。 键是file1的第二列( $2 ),该值是file1的第一列( $1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    运行file2

    • if(a[$1]==""){a[$1]=0}

      如果file1第一列( $1 )中的键不存在于file1 ,则需要0

    • print $1,$2,a[$1]

      使用print打印(使用printfile2的第一列和第二列,使用file2的第一列( $1 )的键print键值结构的值

      要么

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      使用printf打印(使用printffile2的第一列和第二列,使用file2的第一列( $1 )的键打印键值结构的值。

      • FS是从输入文件中获取的列之间的分隔符

      • "%s%s%s%s%s\n"

        是输出的格式

        • %s – 字符串

        • \n – 换行

使用q :

 $ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 " 111 x1 a 222 x2 b 333 x3 c 444 x4 0 555 x5 0 666 x6 d 777 x7 e 888 x8 0 

有时这种方式可能更具可读性。