成对删除重复的行?

通配符

我今天遇到了这个用例。这看似简单乍看之下,但摆弄周围有sortuniqsedawk透露,这是平凡的。

如何删除所有成对的重复行?换句话说,如果给定行的重复数为偶数,则将其全部删除;否则,将其删除。如果重复行数为奇数,请删除除一行以外的所有行。(可以假设输入是排序的。)

干净优雅的解决方案是可取的。

输入示例:

a
a
a
b
b
c
c
c
c
d
d
d
d
d
e

输出示例:

a
d
e
通配符

sed发布此问题后不久,我就得出了答案。sed到目前为止,没有人使用过

sed '$!N;/^\(.*\)\n\1$/d;P;D'

稍微处理一下更普遍的问题(如何删除三行或四行或五行中的行?)提供了以下可扩展的解决方案:

sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp

扩展以删除三行:

sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp

或删除四边形:

sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp

sed 与大多数其他选项相比,它还有一个额外的优势,那就是它能够真正地在流中运行,所需的存储空间不超过要检查重复项的实际行数。


正如cuonglm在评论中指出的那样,必须将语言环境设置为C,以避免无法正确删除包含多字节字符的行。因此,以上命令变为:

LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章