确定简化 csv 文件中每列的最大列长度(每行一行)

确定简化 csv 文件中每列的最大列长度(每行一行)

为了确定逗号分隔的 csv 文件中每列的最大长度,我编写了一个 bash 脚本。当我在 Linux 系统上运行它时,它产生了正确的输出,但我需要它在 OS X 上运行,并且它依赖于wc可以与 参数一起使用的-LGNU版本--max-line-length

OSX 上的版本wc不支持该特定选项,我正在寻找替代方案。

我的脚本(不是那么好 - 我想这反映了我糟糕的脚本编写能力):

#!/bin/bash

for((i=1;i< `head -1 $1|awk '{print NF}' FS=,`+1 ;i++));
    do echo  | xargs echo -n "Column$i: " && 
    cut -d, -f $i $1 |wc -L  ; done

哪个打印:

Column1: 6
Column2: 7
Column3: 4
Column4: 4
Column5: 3

对于我的测试文件:

123,eeeee,2323,tyty,3
154523,eegfeee,23,yty,343

我知道通过 Homebrew 安装 GNU CoreUtils 可能是一个解决方案,但这不是我想要采取的路径,因为我确信它可以在不修改系统的情况下解决。

答案1

为什么不使用 awk ?

我没有 Mac 来测试,但 length() 是 awk 中的一个非常标准的函数,所以这应该可以工作。

awk 文件:

 { for (i=1;i<=NF;i++) {
    l=length($i) ;
    if ( l > linesize[i] ) linesize[i]=l ;
  }
}
END {
    for (l in linesize) printf "Columen%d: %d\n",l,linesize[l] ;
}

然后运行

mybox$ awk -F, -f test.awk  a.txt
Columen4: 4
Columen5: 3
Columen1: 6
Columen2: 7
Columen3: 4

答案2

与 archemars 类似但有所减少

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

Column4: 4
Column5: 3
Column1: 6
Column2: 7
Column3: 4

也是为了维持秩序

 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]}'

Column1: 6
Column2: 7
Column3: 4
Column4: 4
Column5: 3

答案3

一个perl办法:

$ perl -F, -anle 'map {$h{$_} = length($F[$_]) if length($F[$_]) > $h{$_}} 0..$#F;
    END { print "Column @{[$_+1]}: $h{$_}" for sort {$a <=> $b} keys %h }' file
Column 1: 6
Column 2: 7
Column 3: 4
Column 4: 4
Column 5: 3

答案4

使用(以前称为 Perl_6)

~$ raku -ne 'BEGIN my %h; 
               my @F = $_.split(","); 
               map { %h{$_} = chars(@F[$_]) max %h{$_} }, 0..^@F.elems; 
             END put "Column" ~ $_.key + 1 ~ ": " ~ $_.value for %h.sort: +*.key;'  file  

Raku 是 Perl 编程语言家族的成员,具有对 Unicode 的高级支持,因此字符计数是准确的。这是@cuonglm 优秀的 Perl 代码到 Raku 的翻译。

我们首先使用(类似 awk 的)-ne逐行非自动打印命令行标志:

  1. 散列在 BEGIN 块中声明(注意 的使用my)。印记在 Raku 中是不变的,因此您%稍后会在代码中看到相同的-印记,
  2. 在循环体内,每一行都被读入,以逗号分隔,并分配给数组@F(同样,@-sigil 不会改变)。我们对数组map进行从0..^@F.elems零到一的减法,并在每个位置将哈希分配/更新为字符数。elemsmax
  3. 读入所有行后,执行 END 块。我们对列和字符数进行sort哈希和输出。请注意,默认排序是键上的字符串排序,因此我们使用 进行 numify 。此外,Raku 中的字符串连接是通过波浪号完成的(逗号也可以,但这里使用波浪号是为了澄清)。$_.key + 1$_.value+~

输入示例:

123,eeeee,2323,tyty,3
154523,eegfeee,23,yty,343

示例输出:

Column1: 6
Column2: 7
Column3: 4
Column4: 4
Column5: 3

https://docs.raku.org
https://raku.org

相关内容