2012-06-08 24 views
3

我正在編寫一個快速腳本,用於計算從/ proc/net/dev中提取的數據的單個接口吞吐量,並且出現問題。它將其從字節轉換爲兆字節。(standard_in)1:解析錯誤

這是在我的Ubuntu服務器(3.2.0內核)上工作,但是當我嘗試在舊設備(2.6.18時代)上運行它時,它無法工作。我不確定我做錯了什麼。

這裏是我的代碼片段:

int1_byte_rx=`cat $logfile | grep $int1 | awk '{print $2}' | awk '{sum+=$1} END {print sum}'` 
int1_byte_tx=`cat $logfile | grep $int1 | awk '{print $10}' | awk '{sum+=$1} END {print sum}'` 
int1_rx_thrpt=$(echo "($int1_byte_rx * 0.00000762939453)/$iterations/($time * 60)" | bc -l) 
int1_tx_thrpt=$(echo "($int1_byte_tx * 0.00000762939453)/$iterations/($time * 60)" | bc -l) 

當我運行此我得到以下錯誤(從調試模式):

int1_rx_thrpt=$(echo "($int1_byte_rx * 0.00000762939453)/$iterations/($time * 60)" | bc -l) 
echo "($int1_byte_rx * 0.00000762939453)/$iterations/($time * 60)" | bc -l 
++ echo '(1.13417e+10 * 0.00000762939453)/57/(5 * 60)' 
++ bc -l 
(standard_in) 1: parse error 
(standard_in) 1: parse error 
+ int1_rx_thrpt= 
int1_tx_thrpt=$(echo "($int1_byte_tx * 0.00000762939453)/$iterations/($time * 60)" | bc -l) 
echo "($int1_byte_tx * 0.00000762939453)/$iterations/($time * 60)" | bc -l 
++ echo '(9.78048e+09 * 0.00000762939453)/57/(5 * 60)' 
++ bc -l 
(standard_in) 1: parse error 
(standard_in) 1: parse error 

我已經能夠追查問題回本身,但我不確定如何改正它。

歡迎任何建議。

感謝您的時間,

+0

你可以更容易地用'echo 1.13417e + 10 | bc -l'。 (或者交互式運行'bc -l',只需輸入'1.13417e + 10'。) – sarnold

+0

確實我可以 - 謝謝。從這個信息我可以假設它不喜歡科學記數法。有沒有一個特定的模式允許這個?我的印象是mathlib允許這樣做(它適用於bc版本1.06.95但不是1.06) – Numpty

+0

也不是1.06.94。 –

回答

2

/proc/net/dev沒有足夠大的值,以迫使awk打印在科學記數法的任何輸出,所以我不能容易測試這一點,但這裏是我建議的修復方法:

int1_byte_rx=`cat $logfile | grep $int1 | awk '{print $2}' | awk '{sum+=$1} END {printf "%f", sum}'` 
int1_byte_tx=`cat $logfile | grep $int1 | awk '{print $10}' | awk '{sum+=$1} END {printf "%f", sum}'` 

(注意接近尾聲printf "%f",部。)

訣竅是防止awk自GE擺在首位的科學格式。

+0

那肯定做到了。我認爲新版本假設以%f開頭。感謝您的幫助:) – Numpty

+0

..或者,也許您的新系統的時間不夠長,無法將足夠的數據包切換到科學格式。但看看丹尼斯的回答,這很好。 – sarnold

4

您不需要這些長管道,也不需要使用bc

int1_byte_rx=$(awk -v int="$int1" '$0 ~ int {sum += $2} END {print sum}' "$logfile") 
int1_byte_tx=$(awk -v int="$int1" '$0 ~ int {sum += $10} END {print sum}' "$logfile") 
int1_rx_thrpt=$(awk -v int1_byte_rx="$int1_byte_rx" -v iter="$iterations" -v time="$time" 'BEGIN {printf "%12.2f", (int1_byte_rx * 0.00000762939453)/iter/(time * 60)}') 
int1_tx_thrpt=$(awk -v int1_byte_tx="$int1_byte_tx" -v iter="$iterations" -v time="$time" 'BEGIN {printf "%12.2f", (int1_byte_tx * 0.00000762939453)/iter/(time * 60)}') 

您可以將前兩行合併是這樣的:

read -r int1_byte_rx int1_byte_tx <<< $(awk -v int="$int1" '$0 ~ int {sumrx += $2; sumtx+= $10} END {print sumrx, sumtx}' "$logfile") 

,你就只需要一次讀取日誌文件。

另一種選擇是將整個腳本編寫爲AWK或其他支持浮點運算的語言,如Python或Perl。

+0

這是如此的優雅。尼斯。 – sarnold

+0

@sarnold:謝謝。我讚賞這種讚美。 –

+0

同意:)明天我會玩弄。謝謝! – Numpty