2017-06-21 9 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 

私のエラーログファイルでは、計算の最初の日付のエラーは表示されません。また、エラーログファイルに日付を出力する必要があります。誰でも私になぜ01-01-2007の計算のエラーが来ていないのかを教えてもらえますか?また、期待される出力に示されているように日付を印刷する方法は?

答えて

0

あなたのコードはあまりにも複雑で混乱しています。最初からやり直してください。

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

forループで以下のAWKのコマンドは、所望の出力を印刷し

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} 'が実行されます。だから、私の答えでは、3つのパターンがあります。最初のものは "日付"の行に一致し、2番目のものはすべての "物"の行に一致し、3番目のパターンは "合計"の行に一致します。 – weibeld

+0

関数は他のプログラミング言語と同じように機能します。コード内のどこにでも*定義することができ、定義されている場所では実行されませんが、*呼び出される*場所は私の答えの2箇所です。この関数を導入した唯一の理由は、コード(関数本体のコード)の重複を避けるためです。 'check_if_first_error()'という文を関数本体のコードに置き換えるだけで、関数なしでコードを書き直すことができます。 – weibeld

関連する問題