2017-06-21 53 views
0

我有一個輸入文件來:輸出到日誌文件是如下所示不正確地在bash

Date: 01-01-2007 
thing1 3 7098 22394 
thing2 2 6500 13000 
thing3 20 300 6000 
Overalltotal: 41394 
----------------------------------- 
Date: 04-01-2007 
thing1 10 700 5000 
thing2-Card 48 900 43200 
Overalltotal: 46020 

電流輸出:

Error in calculations: 
Things total for thing1 is wrong: it should be 7000 instead of 5000 
Overalltotal is wrong: It should be 50200 

預期輸出:

Error in calculations:01-01-2007 
    Things total for thing1 is wrong: it should be 21294 instead of 22394 
    Overalltotal is wrong: It should be 40294 
Error in calculations:04-01-2007 
    Things total for thing1 is wrong: it should be 7000 instead of 5000 
    Overalltotal is wrong: It should be 50200 

目前代碼:

#!/bin/bash 

# To create new files based on each date and copy the contents till the dashed line. 
awk -F' ' '{fn=$1".log";sub(/^.* /,"",fn);print>fn;close(fn)}' \ 
    FS='\n' OFS='\n' RS='---+\n' ORS='' $1 

for f in *.log; do 
    (awk 'NF && NR>1 && $0!~/total:/{ 
    r=$2*$3; v=(v!="")? v"+"r : r; 
    if(r!=$4){ things_er[$1]=r" instead of "$4 } 
     err_t+=$4; t+=r; $4=r 
    } 
    $0~/total/ && err_t { 
    print $1,"("v")",$3,t; print "Error in calculations:" | "cat 1>&2"; 
     for(i in things_er) { print "Things total for "i" is wrong: it should be "things_er[i] | "cat 1>&2"; } 
     print "Overalltotal is wrong: It should be "t | "cat 1>&2"; next 
    }1' "$f") 2> error_log 
done 

在我的錯誤日誌文件中,我沒有看到計算中的第一個日期錯誤,我也需要在錯誤日誌文件中打印日期。任何人都可以讓我知道爲什麼2007年1月1日計算中的錯誤不會到來?另外,如何在預期輸出中顯示日期?

回答

0

你的代碼過於複雜和困惑。更好地從頭開始。

for循環打印所需的輸出以下AWK命令:

for f in *.log; do 
    awk ' 
    /Date/ { 
     date=$2; 
    } 

    NF > 2 { 
     r = $2*$3; 
     if(r != $4) { 
     check_if_first_error(); 
     printf "\tThings total for %s is wrong: it should be %d instead of %d\n", $1, r, $4; 
     } 
     overall_total += r; 
    } 

    /total/ { 
     if (overall_total != $2) { 
     check_if_first_error(); 
     printf "\tOveralltotal is wrong: it should be %d instead of %d\n", overall_total, $2; 
     } 
    } 

    function check_if_first_error() { 
     if (!has_previous_error) { 
     printf "Error in calculations: %s\n", date; 
     has_previous_error = 1; 
     } 
    } 
    ' "$f" 
done &>error_log 

error_log

Error in calculations: 01-01-2007 
    Things total for thing1 is wrong: it should be 21294 instead of 22394 
    Overalltotal is wrong: it should be 40294 instead of 41394 
Error in calculations: 04-01-2007 
    Things total for thing1 is wrong: it should be 7000 instead of 5000 
    Overalltotal is wrong: it should be 50200 instead of 46020 
+0

嗯,首先你要明白AWK是如何工作的:一個AWK程序的序列'pattern {action}'語句。每行(或者更確切地說,每條記錄,默認情況下是一行)按順序與每個「模式」進行比較,如果它匹配模式,則執行「{動作}」。因此,在我的答案中,有三種模式,第一種與「日期」行匹配,第二種匹配所有「事情」行,第三種匹配「總計」行。 – weibeld

+0

函數的功能與任何其他編程語言一樣。它們可以在代碼中的任意位置被*定義,並且它們不在被定義的地方被執行,而是被調用的地方(在我的答案的兩個地方)。我介紹這個函數的唯一原因是爲了避免重複一段代碼(函數體中的代碼)。您可以通過用函數體中的代碼替換語句'check_if_first_error()'來重寫代碼而不使用函數。 – weibeld

相關問題