【问题标题】:Match 2 files by first column, output column 2 of file 1 and column 2 and 3 of file 2按第一列匹配 2 个文件,输出文件 1 的第 2 列和文件 2 的第 2 列和第 3 列
【发布时间】:2016-10-20 18:21:46
【问题描述】:

我有 2 个文件。

文件 1 的数据如下:

def!:abcabc:abc123
sdf!:skdfkd:asd432
jkl!:kalsfs:kak323

文件 2 的数据如下:

def!:hi123
fjs!:aaaaa123
bab!:kfksfksasdf123

输出应该是:

abcabc:abc123:hi123

我编写了以下单行代码,但我使用的是 2 个数组:

awk -F ':' -v OFS=':' 'FNR==NR{a[$1] = $0;f[$1] = $2;next} ($1 in a) {print $2,$3,f[$1]}' file2 file1 > output

请解释一下简化版的工作原理。

问候,

安德鲁·史密斯

【问题讨论】:

  • 看来你需要合并文件。如果是这样,请尝试使用sort -m
  • 我正在合并文件,但我只需要特定的列。我已经为我的问题提供了一个解决方案,但是我觉得有一种更简单的方法。
  • sort 只能合并特定列
  • 使用 gnu 排序和 gnu join:join -t: -o 1.2,1.3,2.2 <( sort -t: file1 ) <( sort -t: file2 )
  • @LarsFischer,您应该将其添加为答案

标签: linux csv text awk


【解决方案1】:

如果您对使用 GNU sort 和 GNU join 而不是 awk 的解决方案感到满意,您可以这样做:

join -t: -o 1.2,1.3,2.2 <( sort -t: file1 ) <( sort -t: file2 )

这假定file1file2 没有排序,因此使用sort

  • 选项-t用于设置joinsort的分隔符
  • join的选项-o选择哪个文件的哪些部分用于输出,join的信息页面(info join)有更多信息

【讨论】:

  • 我认为这不需要 GNU coreutils 工具。它也应该使用标准工具。你能注释 GNU 主义吗?
  • @Kusalananda 不,我不能,我只有 linux,所以我不能确定 joinsort 的选项。
  • 由于您没有按其他字段排序,因此排序不需要分隔符。
【解决方案2】:

想想a[] 在您的脚本中的用途:

awk -F ':' -v OFS=':' 'FNR==NR{a[$1] = $0;f[$1] = $2;next} ($1 in a) {print $2,$3,f[$1]}' file2 file1 > output

您将$0 保存在a[$1] 中,因此您将第一个文件的全部内容存储在内存中,但是您永远不会对存储在a[] 中的$0 值进行任何操作。你对a[] 所做的只是测试$1 是否在其中($1 in a),但每次你做a[$1]=$0 你也做f[$1]=$2 所以任何时候$1 in a 是真的,$1 in f 也必须是true 并且那是您在 print 语句中实际使用的内容的数组。所以你可以摆脱a[],然后做:

awk -F ':' -v OFS=':' 'FNR==NR{f[$1] = $2;next} ($1 in f) {print $2,$3,f[$1]}' file2 file1 > output

它会完全按照您的原始脚本工作。您不需要 $1 in f 周围的括号,并且每当您需要 2 个变量(例如 FSOFS)具有相同的值时,最好将它们一起设置为该值而不是单独设置,以便可以编写脚本更通俗的说法是:

awk 'BEGIN{FS=OFS=":"} FNR==NR{f[$1]=$2;next} $1 in f{print $2,$3,f[$1]}' file2 file1 > output

【讨论】:

  • 感谢您的精彩解释!!
  • 还有一件事,当我执行 f[$1] = $2 时,不是将 file2 的第二列存储到数组 f 中吗?如果是这样,那么文件 1 的第一个数组如何在数组 f 中?它们不是相同的列。我对此感到困惑..
  • in 运算符适用于数组索引,而不适用于这些索引所寻址的元素。在您执行f[$1]="foo" 之后,条件$1 in f 为真,而不是条件"foo" in f。 file1 的第 1 列和文件 2 的第 1 列具有您要比较的值。当您使用in 运算符时,您将数组视为数学“集合” - “$1 是否存在 in 数组f[] 的索引集合?”。这有助于澄清吗?
  • 是的,这更清楚了。谢谢!
  • 不客气。如果/当有人发布您决定接受的解决方案时,请记住单击它旁边的复选标记以表明您已接受该答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多