sed 删除行(如果提供的两个模式都不匹配)



我正在尝试创建一个filter命令来减少日志文件中的行,假设每一行都包含由日期、组成的分区

/iamthepath01/20200301/file01.txt
/iamthepath02/20200302/file02.txt
....
/iamthepathxx/20210619/filexx.txt

然后从成千上万的行中,我只想保留路径中有两个字符串的行

/202106
/202105

并删除任何其他线路

我已经试着按照命令

sed -i -e '(/202105|/202106)!d' ~/log.txt

以上命令抛出

sed: -e expression #1, char 24: unterminated address regex

您可以使用

sed -i '//20210[56]/!d' ~/log.txt

或者,如果你需要使用更具体的替代方案并进一步增强模式:

sed -i -E '//(202105|202106)/!d' ~/log.txt

详细信息

  • -i-用于内联文件替换的GNU sed选项
  • -E-启用POSIX ERE regex语法的选项
  • //20210[56]/-匹配/20210,然后匹配56的正则表达式
  • /(202105|202106)-匹配/,然后匹配202105202106的POSIX ERE模式
  • !d-删除与图案不匹配的线条

查看在线演示:

#!/bin/bash
s='/iamthepath01/20200301/file01.txt
/iamthepath02/20200302/file02.txt
/iamthepathxx/20210619/filexx.txt'
sed '//20210[56]/!d' <<< "$s"

输出:

/iamthepathxx/20210619/filexx.txt

sed是错误的工具。如果你想要一个像sed一样脆弱的脚本,那么就使用grep,因为它是一个只用于执行简单g/re/p(因此得名(的工具,就像你正在做的那样:

$ grep '/20210[56]' file
/iamthepathxx/20210619/filexx.txt

或者,如果你想要一个更强大的解决方案,只关注你想要匹配的行的部分,从而避免错误匹配,那么使用awk:

$ awk -F '/' '$3 ~ /^20210[56]/' file
/iamthepathxx/20210619/filexx.txt

这可能对你有用(GNU sed(:

sed -ni '#/20210[56]#p' file

这使用类似seds-ngrep的选项来关闭隐式打印,使用-i选项来就地编辑文件。

通常sed使用/.../进行匹配,但如果转义了第一个分隔符,则可以使用其他分隔符,例如#...#

因此,上面的解决方案将把现有文件过滤到包含/202105/202106的行。

N.B.grep几乎肯定会更快地找到上述线条,然而-i选项的使用可能是选择sed的最终原因(尽管通过将> tmpFile && mv tmpFile file附加到grep解决方案可以实现相同的结果(。

最新更新