2017-12-04 10 views
0

複数のgrep-outputを1つのコマンドで処理する可能性はありますか?複数のマッチごとにコマンドをgrepして実行する方法

私は

<fulldata> 
<value>1</value> 
<value>2</value> 
</fulldata> 
<fulldata> 
<value>2</value> 
<value>3</value> 
</fulldata> 

のようなものを持って、手段、標準偏差を取得し、独自にデータ要素といくつか他のことをやりたいきました。この場合

、私はidealy改行で区切られた、(サンプルデータのための)期待される結果と

function printStatistics { 
     mean1=$(awk -F ';' '{print $1}' $1 | awk '{sum += $1; square += $1^2} END {print sum/NR}') 
     deviation1=$(awk -F ';' '{print $1}' $1 | awk '{sum += $1; square += $1^2} END {print sqrt(square/NR - (sum/NR)^2)}') 
     size=$(cat $1 | wc -l) 
     echo $mean1 $deviation1 $size 
} 

を実行したい:

1,5 0,7 2 
2,5 0,7 2 

cat add.xml | grep "<fulldata" -A 2001 | while read line ; do echo "Line: $line" ; done 

ランニングHow to grep and execute a command (for every match)で提案されているように、各行に1つのエントリが作成されます。私は各エントリのための1つのエントリを(後でawkのものを実行するために)欲しいです。

これはgrepで可能ですか、これは別の言語が適切なユースケースですか?

+5

XMLではなく、行指向のデータ形式です。 'grep'ではなく、適切なXMLパーサーを使用してください。 – chepner

+1

*平均値、標準偏差などを取得する* - 予想される結果を投稿する – RomanPerekhrest

答えて

1

html/xmlをgrepで解析するのは悪い習慣です。なぜなら、信頼できないからです。 Mac OS Xを使用している場合は、xmllintというプリインストールされたcliツールを使用して特定の要素を選択することができます。 Linuxでは、標準のパッケージマネージャを使用して取得することができます。

xgrepもあります。私が知りません。

1

awkレスキュー!

$ awk -v RS='\n?</?fulldata>\n' -F'\n' ' 
     !(NR%2){gsub("</?value>",""); 
       s=ss=0; 
       for(i=1;i<=NF;i++) {s+=$i; ss+=$i^2} 
       printf "%.1f %.1f %d\n", s/NF, sqrt((ss-s^2/NF)/(NF-1)), NF} ' file 

1.5 0.7 2 
2.5 0.7 2 

計算された標準偏差のサンプルでは、​​単一観測(NF == 1)の場合にガードする必要があります。

+0

返信いただきありがとうございます!これは解に非常に近いが、fulldataエントリごとに '0.0 0.0 2 'を返す。これは、結果行にまだが存在するためです。 'for(i = 1; i <= NF; i ++){split($ i、result、"> "); s + =結果[2]; ss + = result [2]^2'を4行目として使用しています(私の例では)。 –

+0

'gsub'はそれらを削除する必要があります。おそらくあなたのawkはそれをサポートしていません。 – karakfa

1

コンプレックスxmlstarlet + awkソリューション:

xmlstarlet ed -u "//fulldata/value" -x "concat(.,',')" add.xml \ 
| xmlstarlet sel -B -t -v "//fulldata" -n \ 
| awk -F, '{ n=NF-1; sum=sq=0; for(i=1;i<=n;i++) { sum+=$i; sq+=$i^2 } 
    printf "%.1f\n%.1f\n%d\n", sum/n, sqrt((sq-sum^2/n)/(n-1)), n }' 

出力:

1.5 
0.7 
2 
2.5 
0.7 
2 
+0

返信いただきありがとうございます!これは機能します。 'printf"%.1f \ n%.1f \ n%d \ n ""を 'printf"%.1f%.1f%d \ n "'に変更すると、 gnuplotを使ってすべての手段をプロットするなど、結果の分析にもっと便利です)。 –

+0

@DavidGeorgReichelt、ようこそ、あなたのフレーズに基づいて現在の書式が選択されました*理想的には改行で区切られました:* – RomanPerekhrest

関連する問題