Shell-Script

重用變數

  • October 13, 2013

我折斷了一天的頭,仍然沒有成功。

我有這個腳本:

#!/bin/ksh

fname=$1

for batchname in $(grep -i "Processing batch" $fname | cut -d "'" -f2)
do
Batch_state=`grep -c -i "Batch '$batchname' was successful" $fname`
if [[ "$Batch_state"  -ge 1 ]];then
{
S_Time=`awk '/[0-9]_[0-9].*successful/{getline;getline;getline;print}' $fname | awk '{print $2}'`
E_Time=`awk '/[0-9]_[0-9].*successful/{getline;getline;getline;getline;print}' $fname | awk '{print $2}'`
echo -e $batchname"\t"$S_Time"\t"$E_Time
}
else
{
echo $batchname encountered an error
}
fi
done

輸出此程式碼正在生成:

02_1231324      14:29:04 15:29:11   14:32:19 15:33:11
79_3097935      14:29:04 15:29:11   14:32:19 15:33:11

期望的輸出:

02_1231324      14:29:04    14:32:19
79_3097935      15:29:11    15:33:11 

樣本輸入:

2013/06/11 14:29:04 <0999> (725102)
Creating batch '02_1231324.0'...
2013/06/11 14:29:04 <0999> (725102)
Batch '02_1231324' was successful
2013/06/11 14:29:04 <0999> (725102)
TMR:Child ZERO, 160 Docs 320 Pgs 3874 KByts Tot 0.42 WAL 0.10 WALIO 0.15 IO 0.03 secs
2013/06/11 14:29:04 <0999> (725102)  Processing batch '02_1231324'
2013/06/11 14:32:19 <0999> (725102)
Total in batch: 160 documents using 4 KBytes
2013/06/11 15:29:11 <0999> (725102)
Creating batch '79_3097935.0'...
2013/06/11 15:29:11 <0999> (725102)
Batch '79_3097935' was successful
2013/06/11 15:29:11 <0999> (725102)
TMR:Child ZERO, 160 Docs 320 Pgs 3874 KByts Tot 0.42 WAL 0.10 WALIO 0.15 IO 0.03 secs
2013/06/11 15:29:11 <0999> (725102)  Processing batch '79_3097935'
2013/06/11 15:33:11 <0999> (725102)
Total in batch: 160 documents using 4 KBytes
TMR:Child ZERO, 160 Docs 320 Pgs 3874 KByts Tot 0.42 WAL 0.10 WALIO 0.15 IO 0.03 secs
2013/06/11 13:26:57 <0999> (725102)  Processing batch '12_2013162201'
2013/06/11 13:26:57 <0999> (725102)
Total in batch: 160 documents using 4 KBytes

那麼,我的腳本有什麼問題?如何獲得所需的輸出?

你可能想要這樣的東西來解析你的日誌:

#!/bin/awk -f
{
   if (/was successful/) {
       bn = $2;
       gsub(/'/, "", bn);
       succ[bn] = 1;
   }
   if (/Processing batch/) {
       bn = $7;
       gsub(/'/, "", bn);
       if (bn in succ) {
           succ[bn,",s"] = $2;
           getline
           succ[bn,",e"] = $2;
       } else
           fail[bn] = 1;
   }
}
END {
   for (val in succ)
       if (val !~ /,/)
           print val " " succ[val,",s"] " " succ[val,",e"];
   for (val in fail)
       print val " encountered an error";
}

在關於輸入資料結構的一些嚴格1假設下,您的原始腳本略微減少到僅1次呼叫)。awk

#!/bin/ksh

fname=$1

for batchname in $(grep -i "Processing batch" $fname | cut -d "'" -f2); do
   Batch_state=`grep -c -i "Batch '$batchname' was successful" $fname`
   if [[ "$Batch_state"  -ge 1 ]]; then
       awk -v b=$batchname '
{
   if ($0 ~ "Processing.*" b) {
       s = $2;
       getline;
       e = $2;
       print b " " s " " e;
       exit
   }
}' $fname
   else
       echo $batchname encountered an error
   fi
done

較短的版本使用grep -A(-A是一個 GNU 擴展,它選擇匹配的行一個數字 - 預設情況下為 1 - 後面的行):

#!/bin/ksh

fname=$1

for batchname in $(grep -i "Processing batch" $fname | cut -d "'" -f2); do
   Batch_state=`grep -c -i "Batch '$batchname' was successful" $fname`
   printf "%s" $batchname
   if [[ "$Batch_state"  -ge 1 ]]; then
       grep -A1 "Processing batch '$batchname'" $fname | cut -f2 -d" " | fmt
   else
       printf "encountered an error\n"
   fi
done

但這些仍在處理文件3 次。請參閱 ChuckCottrill 的答案以了解如何完成。


1似乎批次沒有並行處理,而您想要的實際上是包含Processing batch的行和之後的行。

引用自:https://unix.stackexchange.com/questions/94623