異なる行に表示され、n行ごとに繰り返される2つの値を使用して、awkで連結された10進数入力を計算しますか?

異なる行に表示され、n行ごとに繰り返される2つの値を使用して、awkで連結された10進数入力を計算しますか?

macOSシステムで入力をawkにパイプしました。 2 つの小数値の合計が必要です。 1つは2行目に表示され、もう1つは4行目に表示されます。 5行目ごとに合計結果が必要です。値は、前後のコンマでコロン + スペースで区切られます。 6行目はすべて空です。このパターンは入力が完了するまで繰り返されます。

BB: 728345643856359022, 
SH: 3560836, 
RJ: 1500369, 
DD: 1403849, 
Total:,

BB: 729586953244932948, 
SH: 8560836, 
RJ: 4700360, 
DD: 3403021, 
Total:,

BB: 821334125345384020, 
SH: 5293431, 
RJ: 2642499, 
DD: 2433292, 
Total:,

該当する場合は、which awk出力/usr/bin/awkbrew list --version出力gawk 5.2.1_1。 g/awkでこれは可能ですか?どんな提案にも感謝します!

使用している入力形式を指定するには、次の手順を実行します。

getlist | awk '{print $1 $2}' \
| grep 'BB\|SH\|RJ\|DD' \
| sed 's/"//g' \
| awk '{print;} NR % 4 == 0 { print "Total:,";}' \
| awk '{print;} NR % 5 == 0 { print "";}' \
| awk '{print $1 $2}'

期待される出力

BB: 728345643856359022, 
SH: 3560836, 
RJ: 1500369, 
DD: 1403849, 
Total: 4964685,

BB: 729586953244932948, 
SH: 8560836, 
RJ: 4700360, 
DD: 3403021, 
Total: 11963857,

BB: 821334125345384020, 
SH: 5293431, 
RJ: 2642499, 
DD: 2433292, 
Total: 7726723,

答え1

まず、パイプラインを少し単純化してみましょう。どの出力が生成されるかはわかりませんが、表示されるgetlist内容によれば、Totalその行を追加しないマイナーな変更になります。構文解析が難しくなるだけなので、後で追加します。

getlist | 
 tr -d '"' |
 awk '/BB|SH|RJ|DD/{print $1 $2}; NR % 5 == 0 { print ""}' 

|必要なく、どこからでも列を包むことができます\。すべてのステップを1つにまとめてawk置換trを使用してsed単純化することができます(違いは小さいが速度を上げることができます)。

これを念頭に置いて、残りawkの部分を得るために少し拡張することができます。

getlist | 
 tr -d '",' |
 awk '/BB|SH|RJ|DD/{
        print $1 $2","; 
        if(/SH/){ sh = $2 } 
        if(/DD/){ printf "Total: %d,\n", sh + $2 }
      }
      NR % 5 == 0 { print ""}' 

数値処理(数値ではない)を容易にするために削除する,文字を追加したので、awkのさまざまな呼び出しにもその文字を再追加しました。tr,print


私が誤って理解した場合は、元のパイプラインにすでに存在する出力を使用して同じことを行う方法があります(例をとして保存しましたfile)。

$ awk '{ 
         if(!/Total/){print; 
           if(/SH/){ sh = $2 } 
           if(/DD/){ val = sh + $2 }
         }
         else{
            print "Total:",val","
         }
        }' file
BB: 728345643856359022, 
SH: 3560836, 
RJ: 1500369, 
DD: 1403849, 
Total: 4964685,

BB: 729586953244932948, 
SH: 8560836, 
RJ: 4700360, 
DD: 3403021, 
Total: 11963857,

BB: 821334125345384020, 
SH: 5293431, 
RJ: 2642499, 
DD: 2433292, 
Total: 7726723,

答え2

データにタグ値のペアがある場合は、まずこれらのマップの配列(下)を作成するのが最善です。m[]次に、関連付けられた名前を使用してその配列にインデックスを付けることで、単に値を取得できます。 awkを使用してください。

$ awk -F': *' -v OFS=': ' '{m[$1]=$2} $1=="Total"{$2=(m["SH"] + m["DD"])","} 1' file
BB: 728345643856359022,
SH: 3560836,
RJ: 1500369,
DD: 1403849,
Total: 4964685,

BB: 729586953244932948,
SH: 8560836,
RJ: 4700360,
DD: 3403021,
Total: 11963857,

BB: 821334125345384020,
SH: 5293431,
RJ: 2642499,
DD: 2433292,
Total: 7726723,

答え3

これは、既存の出力を活用し、希望する新しい出力を達成する方法です。 gawk 5.1.0でうまく動作します。

$ awk '/^SH/{a=$2}/^DD/{b=$2}/^Total/{$0="Total: "a+b","}1' input.txt
BB: 728345643856359022,
SH: 3560836,
RJ: 1500369,
DD: 1403849,
Total: 4964685,

BB: 729586953244932948,
SH: 8560836,
RJ: 4700360,
DD: 3403021,
Total: 11963857,

BB: 821334125345384020,
SH: 5293431,
RJ: 2642499,
DD: 2433292,
Total: 7726723,
$

関連情報