awk - 计算整列中的模式

awk - 计算整列中的模式

我有以下包含 2 列的 csv 文件:

Header1,Header2
AU3CB0222255,EBFXFR
AU3CB0222271,DBFXFR
AU3CB0225233,DBFXFR
AU3CB0225662,DBFXFR
AU3CB0226264,DBFXFR

我想计算第 2 列中不以 开头的字段E

我尝试了下面的命令,但它不能正常工作:

awk '$2 !~ /^E_/ { count++ }END{ print count }' FinalOutput.csv

答案1

您的awk命令有几个问题。

  • 您尚未指定字段分隔符,因此awk在空格处分割行,而不是,。您可以使用-F','命令行选项来设置字段分隔符。
  • 您的正则表达式指出/^E_/,因此会查找不以开头的字段E_(您的第 2 列值都没有),不是只是那些不以 开头的E。去除_
  • 您的命令还会计算标题行。您可以使用FNR内部变量(自动设置为当前行号在当前文件内) 排除第一行。
  • 正如 Rakesh Sharma 所指出的,如果全部以 开头的行,由于使用了未初始化的变量,E该命令将在末尾打印空字符串而不是 a 。0您可以通过打印count+0而不是 来强制解释为数字count

更正后的版本是

awk -F',' 'FNR>1 && $2!~/^E/{count++} END{print count+0}' FinalOutput.csv

请注意,由于我使用了FNR每文件行计数器(而不是全局行计数器NR),因此这也适用于多个输入文件,其中所有文件都有一个标题行,即您甚至可以将其用作

awk -F',' ' ... ' FinalOutput1.csv FinalOutput2.csv ...

答案2

其他一些方法:

  • awk如果条件为真,则默认打印,因此您可以简单地执行以下操作:

    $ awk -F, 'NR>1 && $2!~/^E/' file | wc -l
    4
    
  • 从第二行开始打印文件,并计算您看到逗号后跟非 E 字符的次数(请注意,这假设每行只有一个逗号,如示例所示):

    $ tail -n+2 file | grep -c ',[^E]'
    4
    
  • perl

    $ perl -F, -lane '$c++ if $.>1 && $F[1] !~ /^E/ }{ print $c' file
    4
    
  • sedwc

    $ sed -n '1d; /,[^E]/p' file | wc -l
    4
    

答案3

你很接近,awk -F, 'NR>1{if ($2 !~ /^E/){count++}} END {print count}'应该可以工作。

-F,告诉 awk 这,是分隔符

NR>1剥离标题

我在您的示例文件上运行了它,它产生了正确的输出

答案4

awk吞咽整个文件(使 NR 为 1)

$ awk -F '\n[^\n]*,[^E]' '{ print NF-1 }' RS='^$' file
4

PCRE 模式下的 GNU grep

$ < grep -zoP '\n.*\K,[^E]'  | xargs -r0 -n1 | wc -l
4

Perl 处于 slurp 模式

$ perl -F'\n.*,[^E]' -pal -0777e '$_=$#F' file 
4

POSIX grep /头

$ { head -n 1 > /dev/null; grep -c ',[^E]'; } < file
4

GNU sed在扩展正则表达式模式下

$ sed -Ee "
    1d;/,[^E]/{z;H;}
    \$!d;g;y/\n/d/
    :a
      s/d{10}/#/g
      s/#([0-9]*)$/#0\1/
      $(seq 9 -1 1 | xargs -I {} printf 's/d{%d}/%d/;' {} {})
      y/#/d/
    ta
    s/^\$/0/
" file
4

相关内容