나는 다음과 같은 기록을 가지고 있습니다 :
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
"ODSTATION BUSY"에 대해 grep을 수행해야 하며, 발견되면(위 레코드에 표시된 대로) "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
샘플 데이터에서 0019093203을 생성하는 POSIX 호환 sed 솔루션(송장 정보가 "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