sed命令:bash中的regex排除某些字符串

时间:2017-09-06 07:04:02

标签: regex linux bash shell regex-negation

我想要排除剪辑和日期中的所有内容,但要选择所有其他数据。

数据:

02.04.2001 ERROR (User1) Server can't start
01.02.2005 ERROR (User2) Server can't start
07.08.2006 ERROR (User1) Problem with Login
12.05.2009 ERROR (User2) Problem with Login

期望的输出:

ERROR  Server can't start
ERROR  Server can't start
ERROR  Problem with Login
ERROR  Problem with Login

我尝试了类似sed -n "s/^.*ERROR/ERROR/p"的内容,以便在开头排除日期。这很有用。

我无法弄清楚如何排除"(用户)"字符串。

4 个答案:

答案 0 :(得分:0)

尝试:

$ sed -n "s/[^)]*ERROR ([^)]*)/ERROR/p" file
ERROR Server can't start
ERROR Server can't start
ERROR Problem with Login
ERROR Problem with Login

我们添加了捕获用户字符串的正则表达式([^)]*)

如果字符串ERROR可能在该行中出现多次,我们会将ERROR之前的正则表达式从.*更改为[^)]*。这可以防止正则表达式匹配ERROR字符串后可能出现的任何(User1)字符串。

请注意,前导^是不必要的。 Sed的正则表达式匹配最左边最长的匹配。这意味着.*ERROR将始终从行的开头开始匹配。

答案 1 :(得分:0)

只需 awk

awk '{ $1=$3=""; sub(/^ */,"",$0) }1' file
  • $1=$3="" - 清除第1和第3个字段

  • sub(/^ */,"",$0) - 在行首

  • 删除多余的空格

输出(因为你想要的输出在第1和第2项之间有 2 - 空格分隔符):

ERROR  Server can't start
ERROR  Server can't start
ERROR  Problem with Login
ERROR  Problem with Login

答案 2 :(得分:0)

我会用这样的东西:

sed -E 's/^\S+\s+//; s/\(\S+\)//g; s/\s\s*/ /g' file

,其中

  • -E选项启用ERE syntax;
  • s/^\S+\s+//删除非空格字符,后跟一个或多个空格字符(即日期和后面的空格);
  • s/\(\S+\)//g删除了parens中的序列;
  • s/\s\s*/ /g用一个空格替换重复的空格。

测试

$ cat sample 
02.04.2001 ERROR (User1) Server can't start
01.02.2005 ERROR (User2) Server can't start
07.08.2006 ERROR (User1) Problem with Login
12.05.2009 ERROR (User2) Problem with Login
12.05.2009 ERROR (User2) Problem (sfsdfsdf(sdfsdf)sdfsf) with (another) aaa) Login
12.05.2009 ERROR (User2) Problem with asdfsdf(sadfasdf) Login
12.05.2009 ERROR (User2) Problem (sfsdfsdf(sdfsdf)sdfsf)aa with (another) aaa) Login

$ sed -E 's/^\S+\s+//; s/\(\S+\)//g; s/\s\s*/ /g' sample
ERROR Server can't start
ERROR Server can't start
ERROR Problem with Login
ERROR Problem with Login
ERROR Problem with aaa) Login
ERROR Problem with asdfsdf Login
ERROR Problem aa with aaa) Login

使用Perl几乎一样:

perl -pe 's/^\S+\s+//; s/\(\S+\)//g; s/\s{2,}/ /g' file

答案 3 :(得分:0)

在awk中。 gsub会更容易,但我有意使用match我忘记了(:

$ awk '
{
    while(match($0,/(^| )(([0-9]{2}\.){2}[0-9]{4}|\([^)]*\))($| )/))
        $0=(RSTART==1?"":substr($0,1,RSTART)) substr($0,RSTART+RLENGTH)
}1' file
ERROR Server can't start
ERROR Server can't start
ERROR Problem with Login
ERROR Problem with Login

它使用match(不是我们所有人)以及括号内的字符串和substr搜索(给定类型)日期。