如何使用awk打印最大长度的数据?

问题描述 投票:0回答:3

我有这个输入:

1 happy,t,c,d
2 t,c
3 e,fgh,k
4 yk,j,f
5 leti,j,f,g

我想打印最大项目的长度(使用逗号作为分隔符),这应该产生:

 1 5,1,1,1
 2 1,1
 3 1,3,1
 4 2,1,1
 5 4,1,1,1

然后我想选择最终创建的第二列的最大值:

 1 5
 2 1
 3 3
 4 2
 5 4

我怎样才能在awk做到这一点?

1) For the first task I have tried:

awk -v col=$2 -F',' '{OFS=","; for(i=1; i<=NF; i++) print length($i);}' test.data.txt

哪个输出不正确:

7
1
1
1
3
1
3
3
1
4
1
1
6
1
1
1

唯一的问题是我无法正确使用-v选项来只读该列。因此,我将所有数据放在一列中,并从column1和column1和column2之间的空间添加值(从长度开始)。

2) To select the max value, I am doing:

awk -F',' '{OFS="\t"; m=length($1); for(i=1; i<=NF; i++) if (length($i) > m) m=length($i); print m}' test.data.txt

这可以正常工作,但由于第一列的存在,值被添加到最大值,给我:

7
3
3
4
6

代替:

5
1
3
2
4

最后,我想一次合并这两个过程。有关改进的建议吗?

bash awk gawk
3个回答
4
投票
awk -F'[, ]' -v OFS="," '{m=length($2);for (i=3;i<=NF;i++) if (length($i) > m) m=length($i)}{print $1,m}' file
1,5
2,1
3,3
4,2
5,4

对于第一种情况:

awk -F'[, ]' -v OFS="," '{printf "%s",$1;for (i=2;i<=NF;i++) printf "%s%s",(i==2?" ":OFS),length($i)}{print ""}'
1 5,1,1,1
2 1,1
3 1,3,1
4 2,1,1
5 4,1,1,1

更短的替代方案:

awk -F'[, ]' -v OFS="," '{printf "%s ",$1;for (i=2;i<=NF;i++) printf "%s%s",length($i),(i==NF?ORS:OFS)}'

虽然awk中的print打印数据并通过在末尾打印新行来更改行,但printf不会自行更改行。

PS:感谢Ed Morton的宝贵评论。


3
投票

我们从这个数据文件开始:

$ cat data
1 happy,t,c,d
2 t,c
3 e,fgh,k
4 yk,j,f
5 leti,j,f,g

第一项任务:

$ awk '{n=split($2,a,/,/); printf "%2s %s",$1,length(a[1]); for(i=2; i<=n; i++) printf ",%s",length(a[i]); print""}' data
 1 5,1,1,1
 2 1,1
 3 1,3,1
 4 2,1,1
 5 4,1,1,1

第二项任务:

$ awk '{n=split($2,a,/,/); max=length(a[1]); for(i=2; i<=n; i++) if (length(a[i])>max)max=length(a[i]); print $1,max}' data
1 5
2 1
3 3
4 2
5 4

How it works

第二项任务:

  • n=split($2,a,/,/) 我们将字段2的内容拆分为数组a
  • max=length(a[1]) 我们将数组a的第一个元素的长度分配给awk变量max
  • for(i=2; i<=n; i++) if (length(a[i])>max)max=length(a[i]) 如果数组a的任何后续元素大于max,我们更新`max。
  • print $1,max 我们打印第一个字段和max的值。

2
投票

试着打高尔夫球:

gawk -F'[ ,]' '{m=0;for(i=2;i<=NF;i++){l=length($i);if(l>m)m=l}print$1,m}'

perl -MList::Util=max -F'\s+|,' -lne'$,=" ";print shift(@F),max map{length}@F'
perl -MList::Util=max -F'\s+|,' -lne'print"@{[shift(@F),max map{length}@F]}"'
perl -MList::Util=max -F'\s+|,' -lpe'$_="@{[shift(@F),max map{length}@F]}"'    

ruby -F'[ ,]' -lape'$_="#{$F[0]} #{$F[1..-1].map{|e|e.size}.max}"'
© www.soinside.com 2019 - 2024. All rights reserved.