将数组组合成矩阵 - 在单元格之间添加分隔符

将数组组合成矩阵 - 在单元格之间添加分隔符

我想合并两个文件并加上两个文件的第二列。

文件1。

001    A
002    B
003    C
004    D

文件2。

002    D
003    D
005    E
006    F

应合并到文件 3 中,如下所示。

001    A
002    B D
003    C D
004    D
005    E
006    F

我尝试了这个命令,由 andreatsh 在这里建议:使用 AWK 合并两个文件并加上第二列:

$ awk '{ z[$1]=z[$1]$2 } END { for (i in z) print i, z[i] }' file1  file2
002 BD
003 CD
004 D

ETC...

这非常接近,但是我如何在字母之间添加空格呢?

例如,第一行中不要使用“BD”,而应使用“B D”

答案1

是的,你可以使用 Awk 来完成,但 Join 就是为了这个任务而生的:

join -a1 -a2 file1 file2

给定样本的输出:

001 A
002 B D
003 C D
004 D
005 E
006 F

注意运行前需要对文件进行排序join。如果您的 shell 支持,您可以使用以下命令一步完成流程替代:

join -a1 -a2 <(sort file1) <(sort file2)

答案2

正确的工具确实是join正如卡西莫多向你展示的那样,但您也可以使用相同的 awk 命令,只需进行很小的修改:

$  awk '{ z[$1]=z[$1]" "$2 } END { for (i in z) print i, z[i] }' file1  file2
002  B D
003  C D
004  D
005  E
006  F
001  A

我只是z[$1]=z[$1]$2改为z[$1]=z[$1]" "$2.

答案3

我添加004 D到 file2 所以我们有一个不明显的案例来测试。鉴于此,要么这样:

$ sort -k1,1 -s file1 file2 |
awk '
    $1 != prev { if (NR>1) print ""; printf "%s", $1; prev=$1 }
    { printf " %s", $2 }
    END { print "" }
'
001 A
002 B D
003 C D
004 D D
005 E
006 F

或这个:

$ sort -k1,1 -s file1 file2 |
awk '
    $1 != prev{if (NR>1) print ""; printf "%s", $1; prev=$1; delete seen }
    !seen[$2]++ { printf " %s", $2 }
    END { print "" }
'
001 A
002 B D
003 C D
004 D
005 E
006 F

取决于您希望如何处理同一键的重复值。只要列出任意数量的文件就行了sort。上面假设 GNU sort for-s保留相同键的输入顺序,如果您没有它并且实际上需要它,则有简单的替代方案。如果您愿意,您还可以进行简单的调整,以便始终让 ABC 等在每个输出行上按字母顺序排列,而不是按它们在每个输入文件中出现的顺序排列,例如:

$ head file*
==> file1 <==
001    A
002    E
003    F
004    D

==> file2 <==
002    D
003    D
004    D
005    E
006    F

==> file3 <==
001    A
002    E
003    C
004    D

$ sort -s file* | awk '$1 != prev{if (NR>1) print ""; prev=$1; delete seen; printf "%s", $1} !seen[$2]++{printf " %s", $2} END{print ""}'
001 A
002 D E
003 C D F
004 D
005 E
006 F

相关内容