![Grep 查找字符串,然后从记录中回显字符串](https://linux22.com/image/83319/Grep%20%E6%9F%A5%E6%89%BE%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E7%84%B6%E5%90%8E%E4%BB%8E%E8%AE%B0%E5%BD%95%E4%B8%AD%E5%9B%9E%E6%98%BE%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我有以下记录:
MiraServ.log.10:2016/02/07 15:25:13 3 All stations busy!!
MiraServ.log.10:2016/02/07 15:25:13 1 TranHasError (3627,-2) EDxxxxxxxxxxxxxxx,MI1,IN0019093203,A113214,TK00:027031636:0617:_:V:166056:_:LCLCOCMSN1:LCLCOCMSN1:1448175096,MTR,VOMiraServJava_2_0_13,TH3627,CY124,TC11,SIZ01572S?,O9i5LLI1Yd2XgI90oZ,OA01,HDxxxxxxxxxxxxxx,ABD,RC776,AR776,OMNOT COMPLETED,ODSTATION BUSY,DMNOT COMPLETED,RENOT COMPLETED,RMNOT COMPLETED,RYL
MiraServ.log.10:2016/02/07 15:25:13 1 Request -> EDxxxxxxxxxxxxxxx,MI1,IN0019093203,A113214,TK00:027031636:0617:_:V:166056:_:LCLCOCMSN1:LCLCOCMSN1:1448175096,MTR,VOMiraServJava_2_0_13,TH3627,CY124,TC11,SIZ01572S?,O9i5LLI1Yd2XgI90oZ,OA01,HDxxxxxxxxxxxxxx,ABD,RC776,AR776,OMNOT COMPLETED,ODSTATION BUSY,DMNOT COMPLETED,RENOT COMPLETED,RMNOT COMPLETED,RYL,ATV,CDVisa,OL01
MiraServ.log.10:2016/02/07 15:25:13 1 TxSendPOSResp 0 5 (661) -> EDxxxxxxxxxxxxxxx,MI1,IN0019093203,A113214,TK00:027031636:0617:_:V:166056:_:LCLCOCMSN1:LCLCOCMSN1:1448175096,MTR,VOMiraServJava_2_0_13,TH3627,CY124,TC11,SIZ01572S?,IDi5LLI1Yd2XgI90oZ,OA01,HDxxxxxxxxxxxxxx,ABD,RC776,AR776,OMNOT COMPLETED,ODSTATION BUSY,DMNOT COMPLETED,RENOT COMPLETED,RMNOT COMPLETED,RYL,ATV,CDVisa,OL01,SRN,VEN,CL01,RL01,RO776,RUN,RI ,CX** TRANSACTION RECORD **\n\nTran. #: 3627\n\nVisa Credit Auth Only\nxxxxxxxxxxxx6056 S\n\n Amount CAD$132.14\n\n########################\n NOT COMPLETED \n########################\n (776) \nZ01572S?/\nInvoice #: 0019093203\n2016/02/07 15:25:13\n\n Customer Copy\n,DECredit Auth Only
我需要 grep 查找“ODSTATION BUSY”,如果找到它(如上面的记录中所示),我需要回显“Invoice #:”后面的整数,0019093203
在这种情况下就是这样。
文件中实际上有数千条这样的记录.log
,我需要获取具有上述字符串的所有记录的发票编号。我希望在 Bash 中做到这一点。
答案1
perl -e 'while(<>) {if ($_ =~ qr/ODSTATION BUSY/) { print "$1\n" if $_ =~ /Invoice #:\s+(\d+)/ } }' <yourfile_goes_here>
哦,巴什?
grep 'ODSTATION BUSY' filename |egrep -o 'Invoice[^0-9]+[0-9]+'|egrep -o '[[:digit:]]+'
或者:
awk 'BEGIN{$0 ~ /ODSTATION BUSY/}; gsub(/^.*Invoice #: /,""){print $1}' filename |sed 's/\\n.*$//g'
答案2
符合 POSIX 标准的 sed 解决方案,从样本数据生成 0019093203(假设发票信息遵循“ODSTATION BUSY”):
sed '/.*ODSTATION BUSY.*Invoice #: */!d; s///; s/\\n.*//' file
don_crissti 处理这两种情况的方法的调整版本:
sed -n '/ODSTATION BUSY/s/.*Invoice #: \([0-9]\{1,\}\)\\n.*/\1/p' file
答案3
这样做的一种方法是:
$ grep "ODSTATION BUSY" <filename> | sed 's/^.*Invoice #://;s/\n.*$/'
这非常难看,我确信还有其他可能更好的方法可以使用诸如awk
.
答案4
如果行太多,例如数千行,我更喜欢使用临时文件,而不是将它们提取到内存中并导致系统负载,但这是我的偏好。
grep "ODSTATION BUSY" logfile > workfile
cat workfile | while read line
do
invoffset=$(echo ${line} | grep -b -o "Invoice #:"|cut -d: -f1) #locates string position from the beginning of the string
invoiceno=$(echo ${line} | cut -c ${invoffset}- | cut -d: -f2 | cut -d"\\" -f1) # cuts the beginning part of the string, then cuts what is before :, then cuts what is after \
echo ${invoiceno}
done