0

I have the following record:

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

I need to grep for "ODSTATION BUSY" and if it is found (as it would be in the record above), I need to echo back the integer after "Invoice #:" which would be 0019093203 in this case.

There are literally thousands of these records one after another in a .log file and I need to get the Invoice number for all records that have the string mentioned above. Im looking to do this in Bash.

0
1

perl -e 'while(<>) {if ($_ =~ qr/ODSTATION BUSY/) { print "$1\n" if $_ =~ /Invoice #:\s+(\d+)/ } }' <yourfile_goes_here>

Oh, Bash?

grep 'ODSTATION BUSY' filename |egrep -o 'Invoice[^0-9]+[0-9]+'|egrep -o '[[:digit:]]+'

Or:

awk 'BEGIN{$0 ~ /ODSTATION BUSY/}; gsub(/^.*Invoice #: /,""){print $1}' filename |sed 's/\\n.*$//g'

0
1

POSIX-compliant sed solution which produces 0019093203 from the sample data (assumes Invoice information follows "ODSTATION BUSY"):

sed '/.*ODSTATION BUSY.*Invoice #: */!d; s///; s/\\n.*//' file

A tweaked version of don_crissti's approach to handle either case:

sed -n '/ODSTATION BUSY/s/.*Invoice #: \([0-9]\{1,\}\)\\n.*/\1/p' file
1
  • 1
    don_crissti: I added a more flexible alternative, based on your suggestion. Feb 11 '16 at 19:57
0

One way of doing this would be:

$ grep "ODSTATION BUSY" <filename> | sed 's/^.*Invoice #://;s/\n.*$/'

That's pretty ugly, I'm sure there are other, possibly better, ways of pulling this information out using something like awk.

1
  • This doesn't work for me on GNU sed version 4.2.1 Feb 11 '16 at 18:20
0

if there are too many lines, like in the order of thousands, I prefer to use a temporary file rather than extracting them in the memory and causing system load, but this is a preference of mine.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.