扫描文件一次并从中删除不同的东西?

时间:2011-09-16 15:22:38

标签: bash unix

我想从两列textfile中提取信息。目前,我的代码通过3种不同的扫描方式提取此信息:

cut -d',' -f 8 file1.csv | sort -g | uniq -c | wc -l
cut -d',' -f 9 file1.csv | sort -g | uniq -c | wc -l
cut -d',' -f8,9 file1.csv | sort -g | uniq -c | wc -l

我想这样做只扫描一次文件。我也忘了补充一点,我想得到3个不同的行数,而不是全部合并为一个。如果不编写复杂的程序,这可能会以某种方式完成吗?

任何帮助表示赞赏,

泰德。

2 个答案:

答案 0 :(得分:4)

awk -F, '
    { a8[$8]; a9[$9]; a89[$8 FS $9] }
    END {
        c=0; for (e in a8)  c++; print "col 8: "   c
        c=0; for (e in a9)  c++; print "col 9: "   c
        c=0; for (e in a89) c++; print "col 8,9: " c
    }
'

答案 1 :(得分:3)

我使用awkperl(可以使用Python或Ruby代替)来后处理cut的最后一个变体:

cut -d',' -f8,9 file1.csv |
awk -F, '{ field8[$1] = 1; field9[$2] = 1; field89[$1,$2] = 1; }
         END {
             i=0; for (j in field8)  { i++; }; print i;
             i=0; for (j in field9)  { i++; }; print i;
             i=0; for (j in field89) { i++; }; print i;
             }'

或者,简化,因为awk可以分割字段:

awk -F, '{ field8[$8] = 1; field9[$9] = 1; field89[$8,$9] = 1; }
         END {
             i=0; for (j in field8)  { i++; }; print i;
             i=0; for (j in field9)  { i++; }; print i;
             i=0; for (j in field89) { i++; }; print i;
             }' file1.csv

由于该问题假定数据字段等中嵌入逗号没有复杂性,因此这个答案也忽略了这些问题。但请注意,CSV文件通常过于复杂,无法使用cut(甚至awk)等简单工具进行处理。 Perl有适当处理CSV的模块;其他可扩展的脚本语言也是如此。