2016-02-14 234 views
0

我有几个CSV文件有多个列,我想要获取每个列的最大长度,最小长度和每个列的最大长度(最大 - 最小值)列在同一个CSV文件中。例如:使用shell脚本查找CSV文件中列的最小和最大长度

文件:

abc 1234 4 
bcd 23644 534 
c 3232 6 

预期输出:

abc 1234 4 
    bcd 23644 534 
    c 3232 6 

Max Length 3 5 3 
Min Length 1 4 1 
Diff 2 1 2 

下面的脚本用于计算MAX柱长度产生预期输出:

awk -F, ' 
    { for (i=1;i<=NF;i++)l[i]=((x=length($i))>l[i]?x:l[i])} 
    END {for(i=1;i<=NF;i++) print "Column"i":",l[i]} ' 

但有MIN长度脚本的问题:

awk -F"," 'BEGIN { 
    for (i=1;i<=NF;i++) { 
     cur = length($i) 
     if ((min == 0) || (cur < min)) { 
      minlength = i 
      min = cur 
     } 
    } ; 
for (i=1;i<=NF;i++) print $minlength}' 

任何帮助将不胜感激。

+1

中,第二脚本,使用BEGIN,你需要阅读了关于节目BEGIN做了什么。另外,您提到了CSV文件,awk脚本使用逗号作为分隔符,但您的示例中没有逗号。由于“CSV”无论如何都是高度模糊的名称,如果您澄清了您的意思,它可能会有所帮助。特别是,任何领域都有嵌入字段分隔符?如果CSV文件中的某个字段中的值看起来像“”abc“'(即带有外部引号),那么应计算为长度为3还是5?那么''“”“'的长度呢? – peak

回答

3

你只需要设置为最小和基于文件的第一行Max阵列初始值:

awk ' 
    NR==1 {for (i=1; i<=NF; i++) maxlen[i] = minlen[i] = length($i)} 
    { 
     for (i=1; i<=NF; i++) { 
      len = length($i) 
      if (len > maxlen[i]) maxlen[i] = len 
      if (len < minlen[i]) minlen[i] = len 
     } 
    } 
    END { 
     printf "Max Length" 
     for (i=1; i<=NF; i++) printf " %d", maxlen[i] 
     print "" 
     printf "Min Length" 
     for (i=1; i<=NF; i++) printf " %d", minlen[i] 
     print "" 
     printf "Diff" 
     for (i=1; i<=NF; i++) printf " %d", maxlen[i]-minlen[i] 
     print "" 
    } 
' file 
+0

不要使用'l'(字母'el')作为变量名,因为它看起来太像'1'(数字'1'),在一些字体中难以区分,因此混淆了您的脚本。例如,'maxl [i] = l'看起来像是将'maxl [i]'设置为'1'。也许使用'cur'来匹配'max'和'min'? –

相关问题