给定一个包含这样数据的文件(即stores.dat文件)
sid|storeNo|latitude|longitude
2tt|1|-28.0372000t0|153.42921670
9|2t|-33tt.85t09t0000|15t1.03274200
期望的输出:
sid : 3
storeNo : 2
latitude : 16
longitude : 13
返回每列下值的最大长度的语法是什么?
我试过这个,但它不起作用:
nawk 'BEGIN { FS = "|" }
{
for(n = 1; n <= NF; n++) {
if (length($n) > max)
max = length($n)
maxlen[$n] = max
}
}
END {
for (i in maxlen) print "col " i ": " maxlen[i]
} ' stores.dat
更新(感谢Mat的回答 - 我已经解决了这个问题):
awk -F"|" ' NR==1{
for(n = 1; n <= NF; n++) {
colname[n]=$n
}
}
NR>1{
for(n = 1; n <= NF; n++) {
if (length($n)>maxlen[n])
maxlen[n]=length($n)
}
}
END {
for (i in colname) {
print colname[i], ":", maxlen[i]+0;
}
} ' filename
答案 0 :(得分:6)
您的脚本存在一些问题 - 列之间共享max
,而您根本不处理标题行。请尝试以下方法:
$ cat t.awk
#!/bin/awk -f
NR==1{
for(n = 1; n <= NF; n++) {
colname[n]=$n
}
}
NR>1{
for(n = 1; n <= NF; n++) {
if (length($n)>maxlen[n])
maxlen[n]=length($n)
}
}
END {
for (i in maxlen) {
print colname[i], ":", maxlen[i];
}
}
$ awk -F'|' -f t.awk stores.dat
$n
指的是n
列的内容。 n
是列号(在第一个和第二个循环中)。最后一个循环只显示了在awk
中迭代数组的方法。
答案 1 :(得分:0)
我对此的看法是使用纯粹的Bash方法:
#!/usr/bin/env bash
dat=./stores.dat
del='|'
TOKENS=$(head -1 "${dat}" | tr $del ' ')
declare -a col=( $TOKENS )
declare -a max
skip=1
while IFS=$del read $TOKENS; do
if [ $skip -eq 1 ]; then
skip=0
continue
fi
idx=0
for tok in ${TOKENS}; do
tokref=${!tok}
printf "%-10s = %-16s[%2d] " "$tok" "${tokref}" "${#tokref}"
echo "--> max=${max[$idx]} tokref=${#tokref}"
#This works : c=$a>$b?$a:$b
#This doesn't: max[$idx]=${max[$idx]}>${#tokref}?${max[$idx]}:${#tokref}
max[$idx]=$((${max[$idx]:=0}>${#tokref}?${max[$idx]}:${#tokref}))
let idx++
done
printf "\n"
done < ${dat}
for ((idx=0; idx<${#col[@]}; idx++)); do
printf "%-10s : %d\n" "${col[$idx]}" "${max[$idx]}"
done
输出如下:
sid = 2tt [ 3] --> max=0 tokref=3
storeNo = 1 [ 1] --> max=0 tokref=1
latitude = -28.0372000t0 [13] --> max=0 tokref=13
longitude = 153.42921670 [12] --> max=0 tokref=12
sid = 9 [ 1] --> max=3 tokref=1
storeNo = 2t [ 2] --> max=1 tokref=2
latitude = -33tt.85t09t0000[16] --> max=13 tokref=16
longitude = 15t1.03274200 [13] --> max=12 tokref=13
sid : 3
storeNo : 2
latitude : 16
longitude : 13
我已经添加了这个解决方案,因为我喜欢这个挑战并且有一些时间可用。