tail-f | awk和end tail一旦找到数据
我正在尝试构建一个脚本,它tail-f | awk和end tail一旦找到数据,awk,pipe,tail,Awk,Pipe,Tail,我正在尝试构建一个脚本,它tail-f | awk每秒更新一次的日志文件。awk part将根据我的搜索参数仅获取日志文件中所需的部分。输出XML也被捕获到输出文件中。脚本工作正常-如预期的那样 问题-但是,在执行搜索后,由于tail-f,它一直处于挂起状态。你知道如何更新下面的脚本吗?这样一旦捕获了输出XML,它就应该打断尾部了 XMLF=/appl/logs/abc.log aa_pam=${1-xml} [[ ${2-xml} = "xml" ]] && tof=xml_
tail-f | awk
每秒更新一次的日志文件。awk part将根据我的搜索参数仅获取日志文件中所需的部分。输出XML也被捕获到输出文件中。脚本工作正常-如预期的那样
问题-但是,在执行搜索后,由于tail-f
,它一直处于挂起状态。你知道如何更新下面的脚本吗?这样一旦捕获了输出XML,它就应该打断尾部了
XMLF=/appl/logs/abc.log
aa_pam=${1-xml}
[[ ${2-xml} = "xml" ]] && tof=xml_$(date +%Y%m%d%H%M%S).xml || tof=$2
tail -f $XMLF | \
awk ' BEGIN { Print_SW=0; Cnt_line=1; i=0}
/\<\?xml version\=/ { if (Print_SW==1) p_out(Cnt_Line,i)
Print_SW=0; Cnt_line=1;
}
{ Trap_arry[Cnt_line++]=$0;
}
/'${1-xml}'/ { Print_SW=1;
}
/\<\/XYZ_999/ { if (Print_SW==1) p_out(Cnt_Line, i);
Print_SW=0; Cnt_line=1; }
END { if (Print_SW==1) p_out(Cnt_Line, i); }
function p_out(Cnt_Line, i) {
for (i=1;i<Cnt_line;i++) {print Trap_arry[i] | "tee '$tof'" }
}
' | tee $tof
您可以在awk脚本中添加一行,例如:
/some-end-of-xml-marker/ { close(/dev/stdin) ; }
我没有尝试过,但你得到了这样的想法:当你到达文件的末尾时关闭STDIN,这样awk中的循环就停止了,你就到达了结尾部分(没有测试,我希望这被证明是正确的…调用退出
(在结束之前会跳转到结束块)
当awk终止时,下一个write()
到stdout的tail-f
将导致EPIPE
错误。tail知道在这种情况下终止
更新:您在决定出口位置时似乎遇到了一些问题。它不应该在p_out
中,因为您可以从结束XML标记匹配表达式和END
块调用p_out
。请尝试以下方法:
XMLF=/appl/logs/abc.log
aa_pam=${1-xml}
[[ ${2-xml} = "xml" ]] && tof=xml_$(date +%Y%m%d%H%M%S).xml || tof=$2
tail -f $XMLF | \
awk '
BEGIN {
Print_SW=0
Cnt_line=1
i=0
}
/\<\?xml version\=/ {
if (Print_SW==1)
p_out(Cnt_Line,i)
Print_SW=0
Cnt_line=1
}
{
Trap_arry[Cnt_line++]=$0
}
/'${1-xml}'/ {
Print_SW=1;
}
/\<\/XYZ_999/ {
if (Print_SW==1)
p_out(Cnt_Line, i)
Print_SW=0
Cnt_line=1
exit
}
END {
if (Print_SW==1)
p_out(Cnt_Line, i);
}
function p_out(Cnt_Line, i) {
for (i=1;i<Cnt_line;i++) {
print Trap_arry[i] | "tee '$tof'"
}
}
' | tee $tof
XMLF=/appl/logs/abc.log
aa_pam=${1-xml}
[${2-xml}=“xml”]&&tof=xml_$(日期+%Y%m%d%H%m%S)
尾部-f$XMLF|\
awk'
开始{
打印w=0
Cnt_线=1
i=0
}
/\ 基于这个问题,你可以试试
#! /bin/bash
XMLF=/appl/logs/abc.log
aa_pam=${1-xml}
[[ ${2-xml} = "xml" ]] && tof=xml_$(date +%Y%m%d%H%M%S).xml || tof=$2
mkfifo log.pipe
tail -f "$XMLF" > log.pipe & tail_pid=$!
awk -vpar1="$aa_pam" -vtof="$tof" -f t.awk < log.pipe
kill $tail_pid
rm log.pipe
我尝试添加{exit},如下所示——但它并没有等待tail-f和awk执行搜索——而是直接分解。{Trap_arry[Cnt_line++]=$0;}/'${1-xml}'/{Print_SW=1;}/\n您在自己的块中有exit
。任何未绑定到表达式的块在每行输入中计算一次,这意味着您将在读取第一行后立即退出。尝试将exit
移动到处理XML结束标记的块中。好的,我将按照建议删除exit
块,但您能否指导如何在脚本中实现原始响应?不确定具体需要在哪个位置进行更改。在Cnt_行=1之后代码>在前面的代码块中。我按照你的建议尝试了-但是脚本没有做任何事情就结束了。它也不会等待记录进入(tail-f
part),因此不会捕获任何输出XML
但在成功搜索后,它仍然没有分解tail-f | awk部分-我添加了它,如下所示/\n按照您的建议进行了尝试-效果很好。。!!谢谢。。!!我刚刚观察到,在输出文件中没有捕获结束标记值。你能告诉我怎么修吗?我知道了。。必须更换/
#! /bin/bash
XMLF=/appl/logs/abc.log
aa_pam=${1-xml}
[[ ${2-xml} = "xml" ]] && tof=xml_$(date +%Y%m%d%H%M%S).xml || tof=$2
mkfifo log.pipe
tail -f "$XMLF" > log.pipe & tail_pid=$!
awk -vpar1="$aa_pam" -vtof="$tof" -f t.awk < log.pipe
kill $tail_pid
rm log.pipe
/<\?xml version\=/ {
if (Print_SW==1) {
p_out(Cnt_Line)
}
Print_SW=0
Cnt_line=0
}
{
Trap_arry[++Cnt_line]=$0
}
$0 ~ par1 {
Print_SW=1;
}
/<\/XYZ_999/ {
if (Print_SW==1)
p_out(Cnt_Line)
Print_SW=0
Cnt_line=0
}
function p_out(Cnt_Line, i) {
for (i=1; i<Cnt_line; i++) {
print Trap_arry[i] | ("tee " tof)
}
exit 1
}