你如何用sed“调试”正则表达式?

时间:2010-10-29 13:21:10

标签: regex linux debugging sed

我正在尝试使用sed使用正则表达式。我用kiki测试了我的正则表达式,这是一个用于测试regexpd的gnome应用程序,它可以在kiki中运行。

date: 2010-10-29 14:46:33 -0200;  author: 00000000000;  state: Exp;  lines: +5 -2;  commitid: bvEcb00aPyqal6Uu;

我想要什么都不替换author: 00000000000;。所以,我创建了正则表达式,当我在kiki中测试它时可以正常工作:

author:\s[0-9]{11};

但是当我在sed中测试它时,它不起作用。

sed -i "s/author:\s[0-9]{11};//g" /tmp/test_regex.txt

我知道正则表达式有不同的实现,这可能是问题所在。我的问题是:我如何至少尝试“调试”sed发生的事情?为什么不起作用?

8 个答案:

答案 0 :(得分:21)

我的sed版本不喜欢{11}位。处理该行:

sed 's/author: [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];//g'

工作正常。

我调试它的方式正是我在这里所做的。我刚刚构建了一个命令:

echo 'X author: 00000000000; X' | sed ...

并一次删除一个更高级的正则表达式:

  • 使用<space>代替\s,但没有修复它。
  • [0-9]{11}替换为[0-9]的11份副本。

因为我在成功使用sed之前已经使用了正则表达式的所有其他功能,所以已经成为其中之一。

但是,事实上,这个 实际上没有[0-9]的可怕11份副本,你只需要逃避大括号[0-9]\{11\}。我不得不承认我没有尝试过,因为它对倍数有效,我通常不会过于关注sed中的简洁,因为我倾向于使用它更多来快速'n'肮脏的工作: - )

但支撑方法 更简洁,更具适应性,知道怎么做也很好。

答案 1 :(得分:21)

在sed中你需要逃避花括号。 "s/author:\s[0-9]\{11\};//g"应该有用。

Sed没有调试功能。为了测试你,迭代地在命令行上简化,直到你得到一些工作,然后重新构建。

命令行输入:

$ echo 'xx a: 00123 b: 5432' | sed -e 's/a:\s[0-9]\{5\}//'

命令行输出:

xx  b: 5432

答案 2 :(得分:16)

Aurelio Jargas有一个名为sedsed的Python脚本,它将显示sed脚本的逐步执行。像这样的调试器在字面上被采用(例如{)而不是具有特殊含义(例如\{)的情况下不会有太大帮助,特别是对于简单替换,但它会有所帮助当正在调试更复杂的脚本时。

The latest SVN version
The most recent stable release
免责声明:我是sedsed的次要撰稿人。

sedsed example

Brian Hiles编写的另一个sed调试器sd,写成Bourne shell脚本(我没有用过这个)。

答案 3 :(得分:12)

你必须使用-r标志来扩展正则表达式:

sed -r 's/author:\s[0-9]{11};//g'

或者您必须转义{}字符:

sed 's/author:\s[0-9]\{11\};//g'

答案 4 :(得分:2)

您正在错误地使用-i标志。你需要给它一个字符串来放在临时文件上。你还需要摆脱你的花括号。

sed -ibak -e "s/author:\s[0-9]\{11\};//g" /tmp/test_regex.txt

我通常从我知道可行的正则表达式开始调试我的语句(在这种情况下就像's / author // g')。当这工作时,我知道我有正确的论据。然后我逐步扩展正则表达式。

答案 5 :(得分:2)

看起来更像perl正则表达式而不是sed正则表达式。也许你更喜欢使用

perl -pi.orig -e 's/author:\s[0-9]{11};//g' file1 file2 file3

至少可以这样添加-Mre=debug来调试正则表达式。

答案 6 :(得分:1)

如果要调试sed命令,可以使用w(写)命令转储sed与文件匹配的行。

来自sed manpages

  

接受地址范围的命令

     

(...)

     
    

w文件名

         
      

将当前模式空间写入文件名。

    
  

适用于您的问题

让我们使用名为 sed_dump.txt 的文件作为sed转储文件。

1)生成sed转储:

sed "/author:\s[0-9]{11};/w sed_dump.txt" /tmp/test_regex.txt

2)检查文件 sed_dump.txt 内容:

cat sed_dump.txt

输出:

  

它是空的...

3)尝试转义'{'正则表达式控制字符:

sed "/author:\s[0-9]\{11\};/w sed_dump.txt" /tmp/test_regex.txt

4)检查文件 sed_dump.txt 内容:

cat sed_dump.txt

输出:

  

日期:2010-10-29 14:46:33 -0200;作者:00000000000;状态:Exp;行:+5 -2; commitid:bvEcb00aPyqal6Uu;

结论

在步骤4)中,一行已匹配,这意味着sed与该行中的模式匹配。它不能保证正确答案,但这是使用sed本身进行调试的一种方法。

答案 7 :(得分:0)

当您在第一个author: 00000000000之前添加sed时,s已经说明了您替换/的事实。