【问题标题】:Sorting and removing duplicate words in a line排序和删除一行中的重复单词
【发布时间】:2012-02-06 19:59:11
【问题描述】:

sort 命令让我可以按字母顺序排列行并删除重复行。我需要类似的东西,可以对单行上的单词进行排序,将它们按顺序排列,并删除任何重复项。有这个命令吗?

例如:

zebra ant spider spider ant zebra ant

更改为:

ant spider zebra

第一个单词之前或最后一个单词之后没有空格。

【问题讨论】:

    标签: bash sorting


    【解决方案1】:

    这对我有用:

    $ echo "zebra ant spider spider ant zebra ant" | xargs -n1 | sort -u | xargs
    ant spider zebra
    

    您可以使用 xargs -n1 将单行中的单词列表转换为单列,使用 sort -u 并使用 xargs 转换回单行。

    【讨论】:

      【解决方案2】:

      shell 已经构建为解析[:blank:] 分隔的单词列表。因此,使用 xargs 是完全多余的。可以完成“独特”的东西,但使用排序更容易。

      echo $(printf '%s\n' zebra ant spider spider ant zebra ant | sort -u)

      【讨论】:

      • 接受的答案使用 3 个管道,但这个只使用 1 个。+1
      • 我喜欢这个答案。你能扩大对“回声”的需求吗?你能不能只做:printf '%s\n' zebra ant spider spider ant zebra ant | sort -u
      • 啊。我想到了。这是为了让它们再次变成一个字符串,而不是多行。我会把我的评论留给下一个没有立即弄清楚的人。
      【解决方案3】:

      使用tr 将空格更改为新行,然后使用sort,最后将新行更改回空格。

      echo $(tr ' ' '\n' <<< "zebra ant spider spider ant zebra ant" | sort -u)
      

      【讨论】:

      • 比使用 printf 更好。虽然可以在最后放弃额外的 tr 。 +1
      【解决方案4】:

      在此之前的所有答案一次只能排序一行。 以下可用于将此类行的完整列表通过管道传输到其中,它将打印每行的唯一单词的排序列表。

      awk '{ delete a; for (i=1; i<=NF; i++) a[$i]++; n=asorti(a, b); for (i=1; i<=n; i++) printf b[i]" "; print "" }'
      

      感谢@jaypai 在本文中使用的大量语法。

      例子:

      >cat file
      group label wearable edit_group edit_group_order label_max camera_elevation camera_distance name label_min label_max value_min value_max camera_angle camera_elevation id
      id group label wearable edit_group clothing_morph value_min value_max name value_default clothing_morph group
      id label show_simple wearable name edit_group edit_group_order group clothing_morph clothing_morph camera_distance label_min label_max value_min value_max camera_distance camera_angle
      id group label wearable name edit_group clothing_morph value_min value_max value_default
      group label wearable id clothing_morph edit_group edit_group_order label_min label_max value_min value_max name camera_distance camera_angle camera_elevation
      id group label wearable edit_group name label_min label_max value_min value_max wearable
      name id group wearable edit_group id group wearable id group wearable id group wearable value_min value_max
      
      >cat file | awk '{ delete a; for (i=1; i<=NF; i++) a[$i]++; n=asorti(a, b); for (i=1; i<=n; i++) printf b[i]" "; print "" }'
      camera_angle camera_distance camera_elevation edit_group edit_group_order group id label label_max label_min name value_max value_min wearable 
      clothing_morph edit_group group id label name value_default value_max value_min wearable 
      camera_angle camera_distance clothing_morph edit_group edit_group_order group id label label_max label_min name show_simple value_max value_min wearable 
      clothing_morph edit_group group id label name value_default value_max value_min wearable 
      camera_angle camera_distance camera_elevation clothing_morph edit_group edit_group_order group id label label_max label_min name value_max value_min wearable 
      edit_group group id label label_max label_min name value_max value_min wearable 
      edit_group group id name value_max value_min wearable
      

      【讨论】:

      • 好,但是在每一行添加了一个悬空;可以通过将最后一个循环更改为for (i=1; i&lt;n; i++) printf b[i]" "; print b[n] 来修复
      【解决方案5】:

      使用python

      $ echo "zebra ant spider spider ant zebra ant" | python -c 'import sys; print(" ".join(sorted(set(sys.stdin.read().split()))))'
      ant spider zebra
      

      【讨论】:

        【解决方案6】:

        使用perl:

        perl -lane '
          %a = map { $_ => 1 } @F;
          print join qq[ ], sort keys %a;
        ' <<< "zebra ant spider spider ant zebra ant"
        

        结果:

        ant spider zebra
        

        【讨论】:

          【解决方案7】:

          使用awk:

          awk '{for(i=1;i<=NF;i++) a[$i]++} END{for(i in a) printf i" ";print ""}' INPUT_FILE
          

          测试:

          [jaypal:~/Temp] cat file
          zebra ant spider spider ant zebra ant
          [jaypal:~/Temp] awk '{for (i=1;i<=NF;i++) a[$i]++} END{for (i in a) printf i" ";print ""}' file
          zebra spider ant 
          

          【讨论】:

            猜你喜欢
            • 2018-11-20
            • 2018-07-27
            • 1970-01-01
            • 2020-04-02
            • 1970-01-01
            • 2018-01-26
            • 2012-07-16
            • 1970-01-01
            • 2015-11-08
            相关资源
            最近更新 更多