grep/awk stdin限制?

asi*_*ght 1 bash awk grep stdin

我环顾四周,但找不到任何已经回答此问题的人.

我正在编写一个bash脚本,它将读取6个不同的csv文件,并计算所有文件中有多少行一起包含某些标记.

(这是一个联系人列表数据库 - 还有商业或私人电子邮件地址的标签)

以下是我编写的代码示例:

### First Scan - Business emails ###

bus="$(awk 'BEGIN {FS = ","}{print $27}' FILE*full* | grep -c "Business")"

echo "No. of Business Accounts: $bus"

### Second Scan - Private emails ###

priv="$(awk 'BEGIN {FS = ","}{print $27}' FILE*full* | grep -c "Private")"

echo "No. of Private Accounts: $priv"
Run Code Online (Sandbox Code Playgroud)

该脚本返回看似完全正确的值.然而!我知道一个事实,每个文件中的每一行都有标记'business'或'private'在同一位置 - 并且没有空行但是当我将两个结果一起添加时,它不等于完整的行数...大约有45000个失踪......

有没有到任何限制stdingrepawk-全数据库超过200万线长...

请帮忙!:-)

ric*_*ici 5

最有可能的是,数百万行csv中的一些包括带引号的带引号的字段.Awk对引用一无所知; 它只会在逗号上分开.

如果您正在使用Gnu awk,则可以使用该FPAT变量,该变量允许您为字段指定正则表达式,而不是字段分隔符的正则表达式.例如,这将适用于许多CSV文件(如果csv文件使用CR-LF行结尾,则除了行结束问题).(-v var=value大致相当于BEGIN{var="value"},而不仅仅是在Gnu awk中.)

gawk -v FPAT='[^",][^,]*|("[^"]*")*'  
Run Code Online (Sandbox Code Playgroud)

顺便说一句,有没有必要使用grep以及awk.您可以使用awk过滤和计数; 实际上,您可以在同一扫描中执行两个计数:

gawk -v FPAT='[^",][^,]*|("[^"]*")*' '
     $27 ~ /Business/ {++bus}
     $27 ~ /Private/  {++pri}
     END { print "No. of Business accounts", bus
           print "No. of Private accounts", pri}' FILE*full* 
Run Code Online (Sandbox Code Playgroud)

上面的正则表达式非常简单,它不会处理"不正确"的CSV文件(如果你可以将这个单词用于这种松散定义的格式).它匹配:

[^",][^,]*|("[^"]*")*
  |    |  | |  |  | |
  +----+--+-+--+--+-+----- A character other than quote or comma
       |  | |  |  | |
       +--+-+--+--+-+----- Followed by any number of characters other than comma
          | |  |  | |
          +-+--+--+-+--- OR
            |  |  | |
            |  |  | +----- Any number of sequences consisting of
            |  |  |
            +--+--+--------- A quote
               |  |
               +--+--------- Any number of characters other than a quote
                  |
                  +--------- Another quote
Run Code Online (Sandbox Code Playgroud)

因此,第一个替代方案将匹配未加引号的字段,如93.7Private,第二个替代方案将匹配:

  • 引用字段,可能包括逗号: "Blood, sweat and tears"

  • 根据引用加倍规则引用带有内部引号的字段:( """My goodness,"" she said"请参阅RFC 4180的第2.7节.)

它不会尝试匹配反斜杠转义的引号,它们不是标准的一部分(它们也不是由MS Excel生成的,afaik),如果引用的字段错误地包含一个不加引用的引号,它将完全失败.

您可以在上面的程序中使用一个简单的变体来查看未正确解析的行,这可能会让您修复它们,或者调整正则表达式,例如:

gawk -v FPAT='[^",][^,]*|("[^"]*")*' '
     $27 !~ /Business/ && $27 !~ /Private/ {
           print "----"
           print "Error at line " NR:
           print $0
           for (i=1; i<=NF; ++i) printf "%2d: |%s|\n", i, $i
     }' filename
Run Code Online (Sandbox Code Playgroud)