データがあり、結論を出すために文を要約したい。以下の例はデータとは関係ありませんが、アイデアを明確にして複製できるようにするためのものです。
Employee Suzie signed one time.
Employee Dan signed one time.
Employee Jordan signed one time.
Employee Suzie signed one time.
Employee Suzie signed one time.
Employee Harold signed one time.
Employee Sebastian signed one time.
Employee Jordan signed one time.
Employee Suzie signed one time.
Employee Suzan signed one time.
次のように、これらの文の要約を作成します。
Jordan signed 2 time(s)
Dan signed 1 time(s)
Suzie signed 4 time(s)
Suzan signed 1 time(s)
Sebastian signed 1 time(s)
Harold signed 1 time(s)
私はawk
で遊んでみましたが、非常に難しいようです。それからsed
を試しましたが、うまくいきませんでした。 sed
は、物事を見つけて変更するためのものです。
一般的なアプローチは
_$ awk '{ count[$2]++ }
END {
for (name in count)
printf("%s signed %d time(s)\n", name, count[name])
}' <file
Harold signed 1 time(s)
Dan signed 1 time(s)
Sebastian signed 1 time(s)
Suzie signed 4 time(s)
Jordan signed 2 time(s)
Suzan signed 1 time(s)
_
つまり、連想配列/ハッシュを使用して、特定の名前が表示された回数を格納します。 END
ブロックで、すべての名前を反復処理し、それぞれの概要を出力します。
少し見栄えを良くするには、printf()
呼び出しの_%s
_プレースホルダーを_%-10s
_のように変更して、名前に10文字(左揃え)を予約します。
_$ awk '{ count[$2]++ }
END {
for (name in count)
printf("%-10s signed %d time(s)\n", name, count[name])
}' <file
Harold signed 1 time(s)
Dan signed 1 time(s)
Sebastian signed 1 time(s)
Suzie signed 4 time(s)
Jordan signed 2 time(s)
Suzan signed 1 time(s)
_
出力をいじる(退屈しているため):
_$ awk '{ count[$2]++ }
END {
for (name in count)
printf("%-10s signed %d time%s\n", name, count[name],
count[name] > 1 ? "s" : "" )
}' <file
Harold signed 1 time
Dan signed 1 time
Sebastian signed 1 time
Suzie signed 4 times
Jordan signed 2 times
Suzan signed 1 time
_
awk
は関連付けられた配列を使用しており、これは使用しているメモリサイズに制限されますが、代わりに次のように実行できます。
sort -k2,2 infile | uniq -c
または、必要に応じてフォーマットを行います。
sort -k2,2 infile |uniq -c |awk '{ print $3, "signed", $1, "time(s)" }'
このジョブはawk
用です。それを行うには、array[index]
が必要です。
awk 'NF {name[$2]++} END{for (each in name) {print each " signed " name[each] " time(s)"}}' file
Jordan signed 2 time(s)
Dan signed 1 time(s)
Suzie signed 4 time(s)
Suzan signed 1 time(s)
Sebastian signed 1 time(s)
Harold signed 1 time(s)
NF
は余分な空白行を削除するためのものです。データは配列のインデックスと値に格納されます。値は対応するインデックスで参照されます。
フォーマットなしの場合、最も簡単な解決策は
sort|uniq -c
uniq -c
は行をカウントし、それらの行の前にそれらのカウントを付けます。uniqが機能するためにはソートが必要です。
$ sort|uniq -c
asdf
asdf
qwer
[ctrl-d]
2 asdf
1 qwer
正確なフォーマットが必要な場合は、sedまたはawkを使用してフォーマットできます。
awk '{print $2}'|sort|uniq -c|awk '{print($2, "signed" ,$1, "time(s)")}'