【问题标题】:Remove lines based on duplicates described by regex?根据正则表达式描述的重复项删除行?
【发布时间】:2018-05-01 04:31:34
【问题描述】:

假设我有一个这样的文件:

apple   2018-01-01
apple cider 2018-01-05
apple cider 2017-01-06
lemon   2016-12-30
lemon   2017-12-31
lemon juice 2018-03-12
lemon pie 2018-03-30

即,它有 1 个或多个文本列,然后是一个日期。对于 [不同] 日期,一些文本条目会重复。现在,我想删除这些重复项:

apple   2018-01-01
apple cider 2017-01-06
lemon   2016-12-30
lemon juice 2018-03-12
lemon pie 2018-03-30

无论是在一列中,都可以使用this solution。但是,如果我必须通过正则表达式查找重复项,而不是查看特定列,该怎么办? awk 可以处理这个吗?还是有其他解决方法?

谢谢。

【问题讨论】:

  • 请解释为什么需要正则表达式。
  • 删除重复项的标准是什么???应该保留哪个值?
  • @Allan,如果日期之前的文本与该日期之前的先前存在的文本重复,则应将其删除。
  • @agc,好吧,我认为使用正则表达式(如^([A-Za-z ]*)\d+)更容易捕获日期之前的文本(这是要检查是否有重复的文本)。如果这不是必需的并且还有其他方法,那么我全力以赴,并感谢您的提示:)。

标签: regex shell awk substitution


【解决方案1】:

您可以使用awk

awk 'BEGIN{FS="\\s+2"}{a[$1]=2""$2}END{for(i in a){print i,a[i]}}' file.input | sort
apple 2018-01-01
apple cider 2017-01-06
lemon 2017-12-31
lemon juice 2018-03-12
lemon pie 2018-03-30

此解决方案仅在重复出现时保留最后出现的值。 如果你想改变行为,你可以添加一些条件来替换例如更新的值。

您还可以在执行操作之前对文件进行排序。

解释:

  • FS="\\s+2 设置第一列和日期之间的字段分隔符(我假设日期以 2 开头)
  • {a[$1]=2""$2} 然后创建一个数组,其中索引是第一列,并在它们出现时分配值。
  • END{for(i in a){print i,a[i]}} 只会打印结果

【讨论】:

    【解决方案2】:

    假设 file 已经排序,那么:

    1. 使用revuniq

      rev file | uniq -f1 | rev
      

      输出:

      apple   2018-01-01
      apple cider 2018-01-05
      lemon   2016-12-30
      lemon juice 2018-03-12
      lemon pie 2018-03-30
      
    2. 如果目标是删除相反的一组重复项,请添加一组 tacs:

      rev file | tac | uniq -f1 | tac | rev
      

      输出:

      apple   2018-01-01
      apple cider 2017-01-06
      lemon   2017-12-31
      lemon juice 2018-03-12
      lemon pie 2018-03-30
      
    3. 如果目标是保留最早的日期:

      rev file | sed 's/ /:/' | rev | sort -t: -k 1,2gr | 
      tr : ' ' | rev | uniq -f1 | rev
      

      输出:

      apple   2018-01-01
      apple cider 2017-01-06
      lemon   2016-12-30
      lemon juice 2018-03-12
      lemon pie 2018-03-30
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2018-04-27
      • 2013-01-08
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多