Grep para uma string e, em seguida, ecoa uma string de volta de um registro

0

Eu tenho o seguinte registro:

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

Eu preciso grep para "ODSTATION BUSY" e se for encontrado (como seria no registro acima), eu preciso repetir o inteiro após "Invoice #:" que seria 0019093203 neste caso .

Existem literalmente milhares desses registros, um após o outro, em um arquivo .log e eu preciso obter o número da Fatura para todos os registros que possuem a cadeia mencionada acima. Estou procurando fazer isso no Bash.

    
por Adam Ali 11.02.2016 / 18:53

4 respostas

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:]]+'

Ou:

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

    
por 11.02.2016 / 19:17
1

Solução sedIX compatível com POSIX que produz 0019093203 a partir dos dados da amostra (pressupõe que as informações de fatura seguem "ODSTATION OCUPADO"):

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

Uma versão ajustada da abordagem de don_crissti para lidar com qualquer caso:

sed -n '/ODSTATION BUSY/s/.*Invoice #: \([0-9]\{1,\}\)\n.*//p' file
    
por 11.02.2016 / 20:07
0

Uma maneira de fazer isso seria:

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

Isso é muito feio, tenho certeza de que há outras maneiras, possivelmente melhores, de extrair essas informações usando algo como awk .

    
por 11.02.2016 / 18:59
0

se houver muitas linhas, como na ordem de milhares, prefiro usar um arquivo temporário em vez de extraí-las na memória e causar carga no sistema, mas isso é uma preferência minha.

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
    
por 11.02.2016 / 19:17