【问题标题】:AWK: search one column, print list of matches in second columnAWK:搜索一列,在第二列打印匹配列表
【发布时间】:2017-04-01 19:03:18
【问题描述】:

我有以下 TAB 分隔文件:

string1 string2 string3 001 string4
string5 string6 string7 002 string8
string9 string10 string11 003 string12
string13 string14 string15 002 string16

我想使用 awk 打印第 4 列中的所有项目并在其旁边打印第 5 列的匹配列表 (数字为标识符)

001 string4
002 string8, string16
003 string12

我当前的尝试失败了: awk 'BEGIN{FS=OFS="\t"} $4 ~ /^K/ { print $4, print $5 }'

我也不知道如何在比赛的第 2 列中打印一个列表。

【问题讨论】:

  • 如果002 string8 在输入中出现两次,输出应该是002 string8(即显示唯一的$5 值)还是002 string8, string8(即显示重复的$5 值)
  • 字符串应该只出现一次!
  • 那是您接受的脚本的行为方式吗?如果没有,请发布后续问题。在发布示例输入/输出时提出全面的测试用例是件好事。
  • 好的,再次检查,在我的文件中没有重复,所以对于发布的示例,脚本工作正常

标签: bash awk


【解决方案1】:

如下使用Awk

awk 'BEGIN{FS=OFS="\t"}{unique[$4]=(unique[$4] FS $5); next}END{for (i in unique) print i,unique[i]}' file

产生如下输出。请记住,这保留订单,假设它并不重要。

002     string8 string16
003     string12
001     string4

如果您担心逗号分隔的值有问题,请按以下方式处理

awk 'BEGIN{FS=OFS="\t"}{unique[$4]=(unique[$4]?(unique[$4]","$5):($5)); next}END{for (i in unique) print i,unique[i]}' file

产生一个输出

002 string8,string16
003 string12
001 string4

这个想法是

  • 由于Awk 一次处理一行文件,因此创建了哈希映射数组unique,其中$4 是索引,值是$5
  • 当每个索引存在多个$5 值时,这些值将附加到现有值并添加, 分隔符。三元运算符会处理这个问题,它的工作原理是查看数组元素有一个值,如果将新值附加到 ,,或者如果为空,则直接分配 $5 值。
  • END 子句打印形成的哈希映射、键和键值,它们将根据需要获取值。

【讨论】:

    【解决方案2】:

    @tobi:@try:

    awk 'FNR==NR{A[$4]=A[$4]?A[$4]","$NF:$NF;next} ($4 in A){print $4,A[$4];delete A[$4]}'   Input_file  Input_file
    

    检查 FNR==NR(当读取第一个 Input_file 时,此条件为真),因此创建一个名为 A 的数组,其索引为 $4 并将其值与最后一列连接到它自己的第一次读取 Input_file 时,接下来将留下所有下一条语句。然后在包含 $4 的数组 A 中循环,打印值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-04
      • 2014-03-24
      • 2015-11-04
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 2023-02-04
      相关资源
      最近更新 更多