使用公共列合并文件

Pya*_*lli 8 command-line text-processing

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

文件1:

a 111 
b 222 
c 333 
d 666 
e 777 
Run Code Online (Sandbox Code Playgroud)

文件2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8
Run Code Online (Sandbox Code Playgroud)

我想将它们组合如下:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0
Run Code Online (Sandbox Code Playgroud)

笔记:

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

Lil*_*loX 13

使用连接:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1
Run Code Online (Sandbox Code Playgroud)

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

输出将是:“joined field, field 2 of file2, field 1 of file1” ( -o'0,1.2,2.1'),如果缺少字段,则输入 0 ( -e0)

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

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


cho*_*oba 8

join如果文件按照您的示例进行排序,该命令几乎可以满足您的需求:

join -12 -a2 file1 file2 -o2.1,2.2,1.1
Run Code Online (Sandbox Code Playgroud)

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

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0
Run Code Online (Sandbox Code Playgroud)


A.B*_*.B. 5

有点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
Run Code Online (Sandbox Code Playgroud)

或者

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

输出

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0
Run Code Online (Sandbox Code Playgroud)

解释

  • 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) infile2中的键不存在于 中file1,我们需要一个0

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

      打印(使用print)的第一列和第二列file2以及具有第一列($1)的键的键值结构的值file2

      或者

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

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

      • FS 是列之间的分隔符,取自输入文件

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

        是输出的格式

        • %s - 细绳

        • \n - 新队