Regex 将正则表达式从Python格式转换为GNU Sed格式

Regex 将正则表达式从Python格式转换为GNU Sed格式,regex,sed,Regex,Sed,我正在解析一个大约10GB的日志文件,需要通过sed将其提供给用户以捕获一些输出。基于我将在JavaScript中使用的内容,必要的捕获部分是: s/method=""([^"]*)"".*path=""([^"]*)"".*accept=""([^"]*)""/"\1","\2","\3"/ 不幸的是,sed(GNU sed 4.2.1,GnuWin32版)在[^”]*范围内挣扎。它拒绝匹配这些范围。我尝试了其他验收块的变体,使用[a-zA-Z0-9:\\\/.]*和类似的变体,但在块中似乎

我正在解析一个大约10GB的日志文件,需要通过sed将其提供给用户以捕获一些输出。基于我将在JavaScript中使用的内容,必要的捕获部分是:

s/method=""([^"]*)"".*path=""([^"]*)"".*accept=""([^"]*)""/"\1","\2","\3"/
不幸的是,sed(GNU sed 4.2.1,GnuWin32版)在
[^”]*
范围内挣扎。它拒绝匹配这些范围。我尝试了其他验收块的变体,使用
[a-zA-Z0-9:\\\/.]*
和类似的变体,但在块中似乎总是有新字符丢失,实际上我可以接受引号之间保留的任何有效字符。由于sed的*例程是一个贪婪的实现,它在最后的“接受”上也往往有问题“项,将日志条目上的所有其他项一直拉到最后

我需要捕获引号之间的所有内容,忽略日志条目的其余部分

我在这方面已经做了两天了,因为我本来可以直接在python中实现一些愚蠢的事情,如果没有要求的话,它可以从带有sed的脚本中执行。有任何正则表达式大师能帮忙吗

编辑:

关于示例的额外信息,这不会在我的系统上生成匹配项,来自GnuWin32.sourceforge.net集合的sed 4.2.1:
sed-r的/method=“”([^”]*)”“.*path=“”([^”]*)”“.*accept=“”([^”]*)”/“\1”,“\2”,“\3”/”日志文件

这将为某些条目生成匹配项:
sed-r/^.*\method\=”([A-Z]*).*path=“”([A-zA-Z0-9:\/]*).*accept=“”(*)”*/“\1”、“\2”、“\3”/logfile

以下是一些(稍加修改但不太多)行:


这个问题的关键在于Windows shell与
sed
命令的交互。有关详细信息,请参阅本答案的最后一节

unixshell下的演示 作为示例输入,请考虑:

$ cat file
some method=""this is my method"" more stuff path=""My Path""  accept=""Yes"" end of line
以下
sed
命令处理输入:

$ sed -r 's/.*method=""([^"]*)"".*path=""([^"]*)"".*accept=""([^"]*)"".*/"\1","\2","\3"/' file
"this is my method","My Path","Yes"
请注意,需要使用
-r
选项,以使未转义的paren充当分组字符,而不是文字字符

在修订后的问题中使用更复杂的输入:

$ sed -r 's/.*method=""([^"]*)"".*path=""([^"]*)"".*accept=""([^"]*)"".*/"\1","\2","\3"/' input
"GET","/ourapp/foo/bar/AAA-123:1029","application/json, text/javascript, application/sord+xml; q=0.01"

"GET","/ourapp/foo/bar:/AA9.1/ABC-123/record","application/json"

"HEAD","/ourapp/foo/bar:/AA3.4/ABC-123/meta","application/json"
关于
accept
问题,我在示例输入中看到两个
accept
变量:

req_header_accept
req_header_accept-language
因为正则表达式匹配
accept=”“
,所以应该匹配前者,而不是后者

匹配非引号 考虑输入:

$ cat test.txt
Billy "The Kid" Smith
Jimmy "The Fish" Stuart
Chuck "The Man" Norris
sed
命令选择引用的材料:

$ sed -r 's/.*"([^"]*)".*/\1/' test.txt
The Kid
The Fish
The Man
所有这些测试都是在linux下的GNU sed版本4.2.1上完成的

Windows外壳问题 以下是使
sed
命令在Windows上工作的关键点:

  • sed
    命令用双引号括起来。在Windows shell中,命令应该用双引号保护,而不是Unix使用的单引号

  • 如果字符串需要包含双引号,请使用十六进制编码将其写入
    \x22

  • 在Windows下,不带引号的插入符号
    ^
    是转义字符。但是,这并不影响我们,因为在我们的例子中,
    ^
    总是出现在带双引号的字符串中

  • CygWin(如果可用)可以避免Windows shell问题

因此,对于Billy the Kid输入,请尝试:

sed -r "s/.*\x22([^\x22]*)\x22.*/\1/" test.txt
另外,
^
是一个Windows转义字符,但据报道它只起到外部引号的作用

在整个案例中,Bryan报告说,以下措施有效:

sed -r "s/^.*method\=\x22\x22([^\x22]*).*path=\x22\x22([^\x22]*).*req_header_accept=\x‌​22\x22([^\x22]*).*$/\x22\1\x22,\x22\2\x22,\x22\3\x22/" logfile

[^”]*
在GNU
sed
中运行良好。请显示用于调用
sed
的完整命令。(为了获得最佳结果,还显示一些小样本输入和相应的期望输出。)信息添加到原始帖子中,太长,无法发表评论。谢谢。我知道-r。不幸的是,sed似乎被
[^”]*
噎住了。我花了几个小时试图找到这个问题,但找不到解决方案。出于某种原因,它绝对拒绝使用“不引用”集。有三条测试线:比利“孩子”史密斯“鱼”吉米“斯图尔特·查克”男人“Norris This工作,提取引号中的内容:
sed-r's/*”([a-zA-Z]*)“*/\1/'test.txt
,但这不会产生任何结果:
sed-r's/*”([^“]*)“*/\1/'test.txt
您的
sed
命令为我输入的账单(更新答案中的输出)。我在linux上使用GNU-sed,但
[^]*
真的应该在任何
sed
中工作,不管GNU与否。我不熟悉Windows。是否会与Windows shell发生一些交互作用?@Bryan表示,Windows shell存在问题。例如,
扮演
的角色,第二,
^
是一个Windows转义字符。谢谢,这个链接足以让这个愚蠢的东西正常工作。哇,这是对答案的编辑。我会将重写得很重的答案标记为有用,但解锁它的是您提供的,而不是您在答案中提供的重写。
sed -r "s/^.*method\=\x22\x22([^\x22]*).*path=\x22\x22([^\x22]*).*req_header_accept=\x‌​22\x22([^\x22]*).*$/\x22\1\x22,\x22\2\x22,\x22\3\x22/" logfile