awkスクリプトで別のファイル内の2つのフィールドの一部を表示する方法

awkスクリプトで別のファイル内の2つのフィールドの一部を表示する方法

次のファイルがありますcalories

Apple pie s s n
Lemon pie s n n 
Orange pie s s s

s(sugar)の最大発生回数を円グラフに印刷するawkスクリプトがあります。

#!/bin/awk -f
BEGIN{ sugar=0}
{
$1=""
count[++cnt] = gsub("s","")
$0 = ""
for(i=1; i<=cnt;i++){
     $i=count[i]
     if(count[i]>sugar)
          sugar=count[i]
}
}
END{
print $1" "$2" has the largest amount of sugar with" sugar" sugars"
}

私が得た結果は次のとおりです。

2 1 has the largest amount of sugar with 3 sugars

希望の出力:

Orange pie has the largest amount of sugar with 3 sugars

awkスクリプトの実行に使用するコマンドは次のとおりです。

awk -f script.awk calories

答え1

GNU awkを使用し、s砂糖モードに設定されたフィールド区切り文字を使用します。

awk -F'\\<s\\>' '
     sugar<NF{sugar=NF;pie=$1}
     END{print pie "has the largest amount of sugar with " sugar-1 " sugar"}
' file

唯一のステートメントは、行内のsugar数量の変数を設定し、円グラフの名前を設定することです。s

ファイルが解析されると、END文が実行され、必要な文字列が印刷されます。

答え2

数を配列に保存し、新しい値ごとに繰り返す必要はありません。現在の最大値とそのパイを保存するだけです。

#!/bin/awk -f

BEGIN {
  sugar_max = 0;
  pie_max = "";
}
{
  pie = $1; 
  $1 = ""; sugar = gsub("s","");
  if (sugar > sugar_max) {
    sugar_max = sugar;
    pie_max = pie;
  }
}

END {
  printf "%s pie has the largest amount of sugar with %d sugars\n", pie_max, sugar_max;
}

この場合、BEGINawk変数は暗黙的に初期化されるため、ブロックは必ずしも必要ではありません。

答え3

どうですか?

awk '
function SCNT(FLD) { x = $FLD; return gsub (/s/, "&", $FLD)}
SMX < SC = SCNT(0) - SCNT(1) - SCNT(2)  {SMX = SC
                     LN = $0
                    }
END {print "Largest sugar count of", SMX, "in", LN
    }
' file
Largest sugar count of 3 in Orange pie s s s

関連情報