在bash中解析类似于.csv的文件

5

我有一个文件格式如下:

string1,string2,string3,...
...

我需要分析第二列,计算每个字符串的出现次数,并生成以下格式的文件:
"number of occurrences of x",x
"number of occurrences of y",y        
...

我已经成功编写了以下脚本,它可以正常工作:
#!/bin/bash

> output
regExp='^\s*([0-9]+) (.+)$'
while IFS= read -r line
do
    if [[ "$line" =~ $regExp ]]
    then
        printf "${BASH_REMATCH[1]},${BASH_REMATCH[2]}\n" >> output
    fi
done <<< "`gawk -F , '!/^$/ {print $2}' $1 | sort | uniq -c`"

我的问题是: 有更好、更简单的方法来完成这项工作吗?
尤其是我不知道如何解决这个问题:
gawk -F , '!/^$/ {print $2}' miocsv.csv | sort | uniq -c | gawk '{print $1","$2}'

问题在于string2可能包含空格,如果有空格,第二个gawk调用将截断字符串。我也不知道如何打印所有字段“从2到NF”,保留分隔符,分隔符可以连续出现多次。
非常感谢,再见。
编辑:
如所请求,这里有一些示例数据:
(这是一个练习,抱歉创新)
输入:
*,*,*
test,  test  ,test
prova, * , prova
test,test,test
prova,  prova   ,prova
leonardo,da vinci,leonardo
in,o    u   t   ,pr
, spaces ,
, spaces ,
leonardo,da vinci,leonardo
leonardo,da vinci,leonardo
leonardo,da vinci,leonardo
in,o    u   t   ,pr
test,  test  ,test
,   tabs    ,
,   tabs    ,
po,po,po
po,po,po
po,po,po
prova, * , prova
prova, * , prova
*,*,*
*,*,*
*,*,*
, spaces ,
,   tabs    ,

输出:

3, * 
4,*
4,da vinci
2,o u   t   
3,po
1,  prova   
3, spaces 
3,  tabs    
1,test
2,  test  
3个回答

5

在awk中的一行代码:

awk -F, 'x[$2]++ { } END { for (i in x) print x[i] "," i }' input.csv

它在关联数组 x 中存储每个第二列字符串的计数,并最后循环遍历该数组并打印结果。
要获得您所示例的确切输出,需要将其管道传输到 sort(1),将字段分隔符设置为 , 并将排序键设置为第二个字段。
awk -F, 'x[$2]++ { } END { for (i in x) print x[i] "," i }' input.csv | sort -t, -k2,2

当然,前提条件是每行的第二列不包含“,”符号。

谢谢!不幸的是,我对awk不太擅长...它能做到的真是令人难以置信。 - Luca
@Nopaste 确实,它是一个非常强大的工具。如果你有时间,我建议阅读《awk程序设计语言》,它将教你这个(以及更多)内容。 - Filipe Gonçalves

1
你可以制作最终的awk命令:
gawk '{ sub(" *","",$0); sub(" ",",",$0); print }'

或者使用sed来处理这种事情:
sed 's/ *\([0-9]*\) /\1,/'

谢谢。我想我会选择sed版本,似乎是最简单的方法! - Luca
我只做了一个小改动:sed -r 's/^ *([0-9]+) /\1,/' - Luca

0

这里有一个Perl的一行代码,类似于Filipe的awk解决方案:

perl -F, -lane '$x{$F[1]}++; END{ for $i (sort keys %x) { print "$x{$i},$i" } }' input.csv

输出按照第二列字母顺序排序。
@F 自动分割数组从索引 $F[0] 开始,而 awk 字段从 $1 开始。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接