我想解析一个格式如下的日志文件:
INFO: Successfully received REQUEST_ID: 1111 from 164.12.1.11
INFO: Successfully received REQUEST_ID: 2222 from 164.12.2.22
ERROR: Some error
INFO: Successfully received REQUEST_ID: 3333 from 164.12.3.33
INFO: Successfully received REQUEST_ID: 4444 from 164.12.4.44
WARNING: Some warning
INFO: Some other info
我想要一个输出4444的脚本。因此,在包含模式^。* REQUEST_ID的最后一行^。* REQUEST_ID之后提取下一个单词。
到目前为止我所拥有的:
ID=$(sed -n -e 's/^.*REQUEST_ID: //p' $logfile | tail -n 1)
对于匹配模式匹配的行匹配,它会删除与匹配匹配的所有文本,从而仅在匹配后保留文本并打印它。然后我拖尾它以获得最后一行。该怎么做使它只打印第一个单词?
是否有一种更有效的方法可以实现这一目标,然后将其传送到尾部?
答案 0 :(得分:4)
使用awk:
awk '
$4 ~ /REQUEST_ID:/{val=$5}
END {print val}
' file.csv
$4 ~ /REQUEST_ID:/
:匹配字段#4与REQUEST_ID:
匹配的行。
{val=$5}
:将字段5的值存储在变量val。
END {print val}
:关闭文件时,打印最后存储的值。
我使用正则表达式匹配来允许字符串的某些变化,但得到匹配。一个更宽松的匹配(在线的任何地方匹配):
awk ' /REQUEST_ID/ {val=$5}
END {print val}
' file.csv
如果您评估(或需要)速度超过稳健性,则使用(需要报价):
awk '
$4 == "REQUEST_ID:" {val=$5}
END {print val}
' file.csv
答案 1 :(得分:3)
使用GNU sed:
sed -nE 's/.* REQUEST_ID: ([0-9]+) .*/\1/p' | tail -n 1
输出:
4444
使用GNU grep:
grep -Po 'REQUEST_ID: \K[0-9]+' file | tail -n 1
输出:
4444
-P
:将PATTERN解释为Perl正则表达式。
-o
:仅打印匹配行的匹配(非空)部分,每个此类部分位于单独的输出行上。
\K
:从内部记录中删除该点之前的所有内容。
答案 2 :(得分:2)
sed '/^.*REQUEST_ID: \([0-9]\{1,\}\) .*/ {s//\1/;h;}
$!d
x' ${logfile}
<强>普林西:强>
答案 3 :(得分:1)
您可以匹配该号码并替换为该值:
sed -e 's/^.*REQUEST_ID: \([0-9]*\).*$/\1/g' $logfile
答案 4 :(得分:0)
打印行和列相交的字段。
awk 'FNR == 5 {print $5}' file
4444
答案 5 :(得分:0)
如果您不知道搜索词的位置,则为另一个awk
替代。
tac file | awk '{for(i=1;i<NF;i++) if($i=="REQUEST_ID:") {print $(i+1);exit}}'
然而,另一个没有循环
tac file | awk -vRS=" " 'n{print;exit} /REQUEST_ID:/{n=1}'