我的Linux上的bash
脚本有问题。
我的输入如下:
input
Karydhs y n y y y n n y n n n y n y n
Markopoulos y y n n n y n y n y y n n n y
name3 y n y n n n n n y y n y n y n
等...
其中y =是,n =否,这是投票的结果......现在我希望使用awk
来显示每个人(姓名)和该人的姓名和总投票数那个胜利(获得最多y),任何想法?
我这样做:
awk '{count=0 for (I=1;i<=15;i++) if (a[I]="y") count++} {print $1,count}' filename
答案 0 :(得分:1)
这个怎么样?
awk '{ for (i=2;i<NF;i++) { if ($i=="y") { a[$1" "$i]++} } } END { print "Yes tally"; l=0; for (i in a) { print i,a[i]; if (l>a[i]) { l=l } else { l=a[i];name=i } } split(name,a," "); print "Winner is ",a[1],"with ",l,"votes" } ' f
Yes tally
name3 y 6
Markopoulos y 6
Karydhs y 7
Winner is Karydhs with 7 votes
答案 1 :(得分:1)
替代双通awk
$ awk '{print $1; $1=""}1' votes |
awk -Fy 'NR%2{printf "%s ",$0; next} {print NF-1}' |
sort -k2nr
Karydhs 7
Markopoulos 7
name3 6
答案 2 :(得分:1)
这是一个快速(不需要排序,没有明确的&#34; for&#34;循环),一次性解决方案,考虑到关系的可能性:
awk 'NF==0{next}
{name=$1; $1=""; gsub(/[^y]/,"",$0); l=length($0);
print name, l;
if (mx=="" || mx < l) { mx=l; tie=""; winner=name; }
else if (mx == l) {
tie = 1; winner = winner", "name;
}
}
END {fmt = tie ? "The winners have won %d votes each:\n" :
"The winner has won %d votes:\n";
printf fmt, mx;
print winner;
}'
输出:
Karydhs 7
Markopoulos 7
name3 6
The winners have won 7 votes each:
Karydhs, Markopoulos
注意:上面的程序是为了便于阅读,但接受GNU awk显示的换行符。某些awks不允许拆分三元条件。
答案 3 :(得分:1)
这是另一种方法。
{ name=$1; $1=""; votes[name]=length(gensub("[^y]","","g")); }
END {asorti(votes,rank); for (r in rank) print rank[r], votes[rank[r]]; }
它类似于@ mklement0的答案,但它使用asorti()
¹对awk内部进行排序。
name=$1
保存令牌1的名称$1="";
清除令牌1,其副作用是将其从$ 0中移除votes[name]
是一个由候选人姓名gensub("[^y]","","g")
删除了除了$ 0左边的所有内容之外的一切length()
统计他们asorti(votes,rank)
按指数对投票进行排序;此时数组看起来像这样:
votes rank [name3] = 6 [1] = Karydhs [Markopoulos] = 7 [2] = Markopoulos [Karydhs] = 7 [3] = name3
for (r in rank) print rank[r], votes[rank[r]];
打印结果:
Karydhs 7 Markopoulos 7 name3 6
¹asorti()
函数可能在某些版本的awk中不可用
答案 4 :(得分:0)
更简单且符合POSIX的awk
解决方案,由sort
协助:
awk '{
printf "%s", $1
$1=""
yesCount=gsub("y", "")
printf " %s\n", yesCount
}' file |
sort -t ' ' -k2,2nr
printf "%s", $1
仅打印名称字段,不带尾随换行符。$1=""
清除第一个字段,导致重建输入行$0
,使其仅包含投票列。yesCount=gsub("y", "")
执行虚拟替换,利用Awk的gsub()
函数返回已执行替换的 count 这一事实;实际上,返回值是该行上y
值的数量。printf " %s\n", yesCount
然后打印yes票数作为第二个输出字段并终止该行。sort -t ' ' -k2,2,nr
然后按第二个(-k2,2
)空格分隔的(-t ' '
)字段对结果行进行排序,以数字方式(n)
,以相反的顺序排序{{1}因此,最高的是 - 投票计数首先出现。