当文件包含多个符号时如何在两个字符串之间提取

当文件包含多个符号时如何在两个字符串之间提取

我一直在尝试从一个巨大的文件中提取表单数据。我需要一个非常具体的模式,但到目前为止我还是失败了。
我有日志的一致部分:

Machine info and user info blah blah blah [senderID=60, 
ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111, 
servicesList= | BeatController | BeatMaker | WaveShow, client=apache, 

所有行都像这样显示。
从这一行我需要使它看起来像这样:

senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13], 
serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow,  

*注意,“WaveShow”之后的所有内容都是无关紧要的,“senderID”之前的所有内容也是如此

我已经从这里的帖子中尝试过这个命令,

sed -n '/servicesList=/{s/.*servicesList=//;s/\S*=.*//;p}'

但它只打印出来

servicesList= | BeatController | BeatMaker | WaveShow

我尝试使用正则表达式在一些迭代中修改它,使用 grep 和 sed 但没有进展

答案1

如果您想要做的是输出 和 之间的所有内容(包括senderID=和 )WaveShow,,那么您需要以下sed命令:

sed -n 's/.*\(senderID=.*WaveShow,\).*/\1/p'

这将使用\(\)括号捕获这两个字符串之间的所有内容,并使用\1\2等等,如果您有更多捕获)输出它。

请注意,前导.*是“贪婪的”,这意味着如果输入中出现senderID=两次该字符串,则第一个将被丢弃。如果这不是您想要的,那么sed这不是正确的工具;perl可以处理这个。命令则变为:

perl -ne 'print if s/.*?(senderID=.*WaveShow,).*/$1/'

-n意思是“对每一行输入执行一个循环,并且不在循环末尾打印该行”。-e指定要在循环内执行的表达式。

?更改后尽可能少地匹配(即非贪婪地匹配).**括号使 perl 对该部分进行分组并捕获它,然后可以将其用作$1第一次捕获、$2第二次捕获等。

然而,这不是在 Perl 中执行此操作的最佳方式。这要好得多,因为它不涉及不必要地更改字符串、捕获文本并打印:

perl -ne 'print "$1\n" if /(senderID=.*WaveShow,)/'

在 Perl 中可能有更多的方法可以做到这一点,甚至可能更有效。

答案2

结尾的逗号是必需的吗?

如果没有,这应该有效:

grep senderID filename | cut -d '[' -f 2- | cut -d ',' -f -5

输出:

senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow

相关内容