根据正则表达式描述的重复项删除行?
Remove lines based on duplicates described by regex?
假设我有这样一个文件:
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
可以处理吗?或者还有其他解决方法吗?
谢谢。
你可以用 awk
:
awk 'BEGIN{FS="\s+2"}{a[]=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[]=2""}
然后创建一个数组,其中索引是第一列,并在它们出现时分配值。
END{for(i in a){print i,a[i]}}
将只打印结果
假设文件已经排序,那么:
使用 rev
和 uniq
:
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
如果目标是删除相反的一组重复项,则添加一组
共 tac
人:
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
如果目标是保留最早的日期:
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
假设我有这样一个文件:
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
可以处理吗?或者还有其他解决方法吗?
谢谢。
你可以用 awk
:
awk 'BEGIN{FS="\s+2"}{a[]=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[]=2""}
然后创建一个数组,其中索引是第一列,并在它们出现时分配值。END{for(i in a){print i,a[i]}}
将只打印结果
假设文件已经排序,那么:
使用
rev
和uniq
: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
如果目标是删除相反的一组重复项,则添加一组 共
tac
人: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
如果目标是保留最早的日期:
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