2011-12-25 7 views
4

の各列の(長さ)(すなわちstores.datファイル)UNIX - 最大このようなデータを含むファイルを指定したファイル

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 

UPDATE(マットの答えのおかげで - 私はこれに落ち着い):

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

何かがうまくいかないときは、あなたが提供した出力だけでなく、サンプルコードが提供する実際の出力も与えるべきです。 – Gabe

答えて

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 

$nn番目の列の内容を指します。 nは(第1ループと第2ループの)列番号です。最後のループは、配列の反復方法をちょうどawkに示しています。この上

+0

'$ n':現在の行の' n'列の内容です。 'n'は単なる数字です。 – Mat

+0

これは、awkのような10個のエラーを与えます:awk:行2の近くの文法エラーawk:行2の近くの不正な文awk:行6の近くで救済します。 – toop

+0

@toop: 'gawk'がインストールされているかどうか確認してください。 – Mat

0

私のテイクは純粋なバッシュ・アプローチを使用することです:

#!/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 

私は挑戦が好きで、いくつかを持っていたので、私はこのソリューションを追加しました余分な分。

関連する問題