我有这个输入:
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
中执行此操作?
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之间的空格中添加(从长度开始)值。
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
最后,我想一次合并这两个进程。有关改进的任何建议吗?
答案 0 :(得分: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的宝贵意见。
答案 1 :(得分: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
第二项任务:
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 :(得分: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}"'