根据regex描述的重复项删除行?

时间:2018-05-01 04:31:34

标签: regex shell awk substitution

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

 var st = DataProvider.GetEntity<Teacher>().FirstOrDefault();
                var subjectdetail = new SubjectTeacherDetail()
                {
                    Teacher = st
                };
                DataProvider.AddEntity(subjectdetail);
                DataProvider.SaveChanges();

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

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

在一栏中,可以使用this solution。但是,如果不是在特定列中查找,我必须通过正则表达式查找重复项? apple 2018-01-01 apple cider 2017-01-06 lemon 2016-12-30 lemon juice 2018-03-12 lemon pie 2018-03-30 可以处理吗?或者还有其他解决方法吗?

感谢。

2 个答案:

答案 0 :(得分: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]}}只打印结果

答案 1 :(得分:1)

假设文件已经排序,那么:

  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. 如果目标是删除相反的重复项集,请添加一组 tac s:

    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