【问题标题】:Joining lines with a common field specifically with sed?使用 sed 连接具有公共字段的行?
【发布时间】:2018-03-16 05:24:04
【问题描述】:

我已经想出了如何使用 awk 来做到这一点,但我也想找到一种方法来使用 sed 来做到这一点。我在 StackOverflow 上看到的内容要么使用 awk,要么非常神秘,不起作用,也没有提供任何解释来帮助我使其工作。我有这样的输入:

你好1 aaa

你好2 bbb

你好1 ccc

你好1 ddd

并且需要这样的输出:

你好1aaa,ccc,ddd

你好2 bbb

如果你能解释一下这个命令,那就太好了。我已经尝试阅读 sed,但它仍然很混乱。

【问题讨论】:

    标签: unix awk sed


    【解决方案1】:

    我在 StackOverflow 上看到的要么使用 awk,要么非常 神秘,不起作用,也没有提供任何解释来帮助我 让它工作。

    如果你能解释一下这个命令,那就太棒了。我试过了 阅读 sed 但仍然很混乱。

    awk '{arr[$1] = ($1 in  arr ? arr[$1] "," : "") $2 }END{ for(i in arr)print i,arr[i] }' infile
    

    说明:

     awk '{
            # arr is array, index being first field
            # if array arr has key before ($1 in arr), then
            # arr[$1] contains previously stored value arr[$1] plus comma
            # and send field of line read
            # otherwise, just second field of line read
    
            arr[$1] = ($1 in  arr ? arr[$1] "," : "") $2 
          }
       END{ 
            # loop through array arr
            # print array key and value
            for(i in arr)print i,arr[i] 
          }
         ' infile
    

    测试结果:

    $ cat infile
    Hello1 aaa
    Hello2 bbb
    Hello1 ccc
    Hello1 ddd
    
    $ awk '{arr[$1] = ($1 in  arr ? arr[$1] "," : "") $2 }END{ for(i in arr)print i,arr[i] }' infile
    Hello1 aaa,ccc,ddd
    Hello2 bbb
    

    【讨论】:

    • 我知道如何使用 awk 执行此操作,我要求在 sed 中使用等效命令。
    • @Ashley :对不起,我可能看错了,AFAIK 你也要求解释
    • @Ashley 很好,如果你也可以展示你的 sed 实验,我个人很想知道如何做到这一点
    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -r '1h;1d;H;x;s/((\S+) \S+)(.*)\n\2 (\S+)$/\1,\4\3/;x;$!d;x' file
    

    将第一行存储在保持空间 (HS) 中,然后将其删除。对于后续行,将当前行附加到 HS 并在交换到 HS 后,对类似值进行模式匹配并以所需格式替换(如果成功)值。始终交换回模式空间 (PS),然后删除 PS。最后,如果这是最后一行交换到 HS 并打印它的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多