我有以下日志文件:
example.com - - - 127.0.01 [22/Sep/2013:07:22:22 +0000] "POST /api/test.php HTTP/1.1" 200 355 "-" "-" "{\x22id\x22:\x22 ... }}}"
example.com - - - 127.0.01 [22/Sep/2013:07:22:22 +0000] "POST /api/test.php HTTP/1.1" 200 355 "-" "-" "{\x22id\x22:"{\x22 ... }}}"
我想将第一个{\x22
提取到最后}
所以我使用以下sed命令:
cat test.txt | sed -r 's/.+?"(\{.+\})".*/\1/g'
然而,它给了我
{\x22id\x22:\x22 ... }}}
{\x22 ... }}}
但我想要
{\x22id\x22:\x22 ... }}}
{\x22id\x22:"{\x22 ... }}}
答案 0 :(得分:0)
好.+?
不能与sed
一起使用,因为它的正则表达式引擎不支持非贪婪匹配。
但是,如果您考虑perl,则可能:
perl -pe 's/.+?"(\{.+\})".*/\1/g' test.txt
{\x22id\x22:\x22 ... }}}
{\x22id\x22:"{\x22 ... }}}
或使用egrep -o
:
egrep -o '\{.+\}' test.txt
{\x22id\x22:\x22 ... }}}
{\x22id\x22:"{\x22 ... }}}
答案 1 :(得分:0)
使用awk
awk '{sub(/[^{]*{/,"{");sub(/}"/,"}")}1' file
{\x22id\x22:\x22 ... }}}
{\x22id\x22:"{\x22 ... }}}
答案 2 :(得分:0)
Cut="#CuT#"
sed -n --posix "s/\({\\\\x22.*}\)\"$/${Cut}\1/;s/.*${Cut}//p" sample.txt
我使用变量Cut来改变任何其他"标记"取决于要处理的文本内容。如果你确定Cut的值不在文件中,你可以直接在sed中更改它的内容
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed 's/\({\\x22.*}\).*/\n\1/;s/.*\n//' file
贪婪是你在第一场比赛中的敌人所以使用分而治之的习惯用于{\x22
。这是一个唯一的标记(在本例中为\n
)并使用第二个替换命令来删除字符串的第一部分。对于最后一次}
贪婪,你的朋友.*}
将自己找到最后一场比赛。
N.B。如果第一个匹配是单个字符,比如说X
,那么否定的字符类[^X]*
就足够了。但是因为它是一个字符串(两个或多个字符),所以这不起作用。