使用公共列合并文件

使用公共列合并文件

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

文件 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 第一列的子集

答案1

使用连接:

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

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

请参阅命令 join 的手册页

答案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

答案3

有点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}

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

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

    file2过去

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

      如果第一列中的键($1)在file2中不存在file1,我们需要一个0

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

      打印(使用print)的第一列和第二列file2以及键值结构的值,其中第一列的键是($1file2

      或者

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

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

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

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

        是输出的格式

        • %s- 细绳

        • \n- 新队

答案4

使用

$ 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

有时候这样可能更具可读性。

相关内容