2012-09-10 69 views
3

我有過很多線,containts「X_Y = XXXX」,其中XXXX可以是一個數字從0到一些N.文件需要perl的一個襯墊,以獲得特定內容出列,並可能做出平均值

現在, a)我想只在每一行中獲得該行的XXXX部分。 b)我想得到平均值

可能這兩個在一個襯裏。

我嘗試sometihng像

cat filename.txt | grep x_y | (this need to be filled) 

我不知道什麼文件 在過去,我已經使用像

perl -pi -e 's/x_y/m_n/g' 

命令來替換X_Y的所有實例。 但是現在,我想匹配x_y = XXXX並將XXXX取出,然後可能將其平均分配給整個文件。

對此的任何幫助將不勝感激。我對Perl和正則表達式相當陌生。

+0

有幾個很好的解決方案。你可以請你最喜歡的那個作爲接受的答案嗎? –

回答

3

下應該做的:

... | grep 'x_y=' | perl -ne '$x += (split /=/, $_)[1]; $y++ }{ print $x/$y, "\n"' 

}{被通俗地稱爲愛斯基摩操作和作品,因爲代碼的-e周圍-n地方(見perldoc perlrun)。

+2

'perl -F/=/-ane'$ x + = $ F [1]; ...' – Zaid

+0

這是否假定行中只有一個'='?或者這是第一個'='。如果該行具有「a_b = yyyy b_z = uuuu x_y = XXXX」,無論如何將進行檢查並且將會更新,這是否會工作? – AMM

+0

我假設它在這一行只有'x_y = XXXX',我在'/ = /'上分割'$ _',然後從第二個元素(從零開始的索引'[1]')分裂的結果。對於多個空格分隔的賦值,可以執行'/ x_y =(\ S +)/或next; $ x + = $ 1'而不是原始答案中的$ x + = ...'表達式。這甚至會爲你節省'grep'。 –

3

使用AWK:

/^[^_]+_[^=]+=[0-9]+$/ {sum=sum+$2; cnt++} 
END { 
    print "sum:", sum, "items:", cnt, "avg:", sum/cnt 
} 

$ awk -F= -f cnt.awk data.txt 
sum: 55 items: 10 avg: 5.5 

純的bash溶液:

#!/bin/bash 

while IFS='=' read str num 
do 
    if [[ $str == *_* ]] 
    then 
     sum=$((sum + num)) 
     cnt=$((cnt + 1)) 
    fi 

done < data.txt 

echo "scale=4; $sum/$cnt" | bc ;exit 

輸出:

$ ./cnt.sh 
5.5000 
+0

有幾點建議:'IFS ='='read str num'來限制對'read'命令環境的改變。我認爲'x_y'是變量名稱的模式,而不是文字字符串; '如果[[$ str == * _ *]]'(或者只是'?_?')可能更合適。 – chepner

+0

完成,謝謝指出我愚蠢的錯誤。 –

6

Timtowtdi(如常)。

perl -nE '$s+=$1, ++$n if /x_y=(\d+)/; END { say "avg:", $s/$n }' data.txt 
+1

+1:迄今爲止最好的方法,除非OP在一行中有多個'=',因爲他已經暗示需要將其更改爲'$ s + = $ 1,++ $ n,而/ x_y =(\ d + )/ g' – Borodin

+0

@Borodin我喜歡'while'的建議。天哪,Perl很有趣(用小片段)。 – bobbogo

0

作爲單行,與評論分手。

perl -nlwe ' 
    push @a, /x_y=(\d+)/g   # push all matches onto an array 
    }{        # eskimo-operator, is evaluated last 
    $sum += $_ for @a;    # get the sum 
    print "Average: ", $sum/@a; # divide by the size of the array 
' input.txt 

如果它們存在,將提取多行匹配。

糊版:

perl -nlwe 'push @a, /x_y=(\d+)/g }{ $sum += $_ for @a; print "Average: ", $sum/@a;' input.txt 
相關問題