Parsing 使用AWK(或SED)获取字符串之间的文本-包括开始字符串但不包括结束字符串
我试图使用AWK(或SED或两者的组合)解析出包含特定字符串“Parsing 使用AWK(或SED)获取字符串之间的文本-包括开始字符串但不包括结束字符串,parsing,awk,sed,between,Parsing,Awk,Sed,Between,我试图使用AWK(或SED或两者的组合)解析出包含特定字符串“Info:AgentSession”的日志文件。 我想包括包含“Info:AgentSession”字符串的开始行,但不包括结束字符串行,即“[2015-” 以下是CentOS服务器上的文本日志文件片段: 当我运行以下命令时: 我得到以下输出: 但是我希望这个输出包括“Info:AgentSession”的START字符串,因此实际上最终看起来是这样的(使用[2015-字符串的开头,省略日志中不引用START字符串的所有其
Info:AgentSession
”的日志文件。
我想包括包含“Info:AgentSession
”字符串的开始行,但不包括结束字符串行,即“[2015-
”
以下是CentOS服务器上的文本日志文件片段:
当我运行以下命令时:
我得到以下输出:
但是我希望这个输出包括“
Info:AgentSession
”的START字符串,因此实际上最终看起来是这样的(使用[2015-字符串的开头,省略日志中不引用START字符串的所有其他部分)作为结束字符串):
用一个简单的AWK或SED命令可以做到这一点吗?
您可以使用带有
sed的简单循环:
sed -n '/Info:AgentSession/{:a;p;n;/^$/!ba;p}' input.file
该命令搜索包含模式/Info:AgentSession/
的行。如果出现这样的行,则在大括号{}之间显示以下块
get被执行。在该块中,我们为循环定义一个开始标签,简单地调用它:a
。然后我们打印当前行p
,从输入n
中获取下一行,并检查它是否为空/^$/
。如果行不是空的!
我们返回到循环的开始ba
。否则我们打印将该空行用作记录分隔符,然后在下一行输入中再次开始搜索/Info:AgentSession/
使用-n
命令行选项抑制其他行的输出
输出:
[2015-03-30 12:23:10.999][124][Info:AgentSession]处理PieraC的代理消息
请求:破产管理人
行动:不要打扰
[2015-03-30 12:23:11.000][124][Info:AgentSession]向PieraC发送代理消息
答复:破产管理署
请求ID:
状态:Ok
信息:
伊斯雷迪:错
[2015-03-30 12:23:11.502][111][Info:AgentSession]向MatthewW发送代理消息
活动状态:Wrapup
伊斯雷迪:错
这是真的
[2015-03-30 12:23:16.207][124][Info:AgentSession]向PieraC发送代理消息
答复:非查询
状态:Ok
消息:查询已成功发送
[2015-03-30 12:23:16.268][124][Info:AgentSession]PieraC处理代理信息
请求:CallAction
CallDisposition:
另一种方法是像这样使用awk
:
awk -F'\n' '$1 ~ /Info:AgentSession/' RS='\n\n' ORS='\n\n' input.file
我将输入和输出分隔符定义为两个换行符的序列。字段分隔符是单个换行符。如果记录的第一个字段包含模式Info:AgentSession
,则打印整个记录
顺便说一句,上面的sed
命令也可以在不使用-n
选项的情况下编写:
sed '/Info:AgentSession/{:a;n;/^$/!ba;p};d' input.file
在本例中,我们正在搜索包含/Info:AgentSession/
的行,如果找到这样的行,则在大括号之间执行以下块。我们定义一个标签:a
,打印当前行,并从输入n
中获取下一行。只要在/^$/!
后面有非空行,我们就后退一步到循环的开始处,否则我们将该空行打印为记录分隔符p
。使用awk
删除所有其他行d
:
awk '/^[[]/{f=0} /Info:AgentSession/{f=1} f' file
工作原理
awk
循环每一行输入。对于每一行,程序决定将变量f
设置为真(1)还是假(0)。如果f
为真,则打印该行
/^[[]/{f=0}
每当一行以[
开头时,f
被设置为false
/Info:AgentSession/{f=1}
如果该行包含字符串Info:AgentSession
,则覆盖上一个命令并将f
设置为true
f
如果f
为真,则awk
打印该行
上面是f{print$0}
的简写,其中在awk中,$0
表示整行
这可能适合您(GNU-sed):
在第一个块中添加一个print
命令。谢谢@hek2mgl。我尝试了这一点,但我只得到了第一行的输出,而没有得到表达式之间所需的所有行。因此,例如,我只得到一行,看起来像:[2015-03-30 12:23:16.207][124][Info:AgentSession Info]向PieraC发送代理消息[2015-03-30 12:23:16.268][124][Info:AgentSession]处理PieraC的代理消息
,每行下面没有任何部分。是的,出现了一个小错误。(我将N
替换为N
)。它现在应该可以工作了。是的!这对我来说也很有效,再次感谢hek2mgl!@ChrisCharles还检查了我添加的awk
替代方案。它更直观awk
处理,因为它将块简单地定义为记录。太好了!-感谢解决方案+解释@John1024
sed -n '/Info:AgentSession/{:a;p;n;/^$/!ba;p}' input.file
awk -F'\n' '$1 ~ /Info:AgentSession/' RS='\n\n' ORS='\n\n' input.file
sed '/Info:AgentSession/{:a;n;/^$/!ba;p};d' input.file
awk '/^[[]/{f=0} /Info:AgentSession/{f=1} f' file
sed -n '/Info:AgentSession/,/^$/p' file