如何计算一组字符的出现次数?

时间:2018-09-27 17:45:48

标签: regex awk

我正在尝试使用awk记录来计算字段中一组字符的出现次数。

我要计算的字符集如下:

!"#$%&'()*+

我一直在尝试以下内容:

{
    s = $0;
    print(gsub(/!\"#\$%&\'()\*\+/, "",  s);
}

但是,如果我尝试运行此脚本,则会出现语法错误。我认为它可能与escaping of special characters in regex in gawk有关,但是我无法生成有效的脚本。

以下是一个简单的示例:

# prints 1
AAAEEEA#AA

# prints 0
AAAEEEAAAA

# prints 4
AA((EE!!AA

3 个答案:

答案 0 :(得分:1)

revo的评论指出,解决方案是使用字符列表:

{
    s = $0;
    print(gsub(/[!"#$%&'()*+]/, "",  s));
}

答案 1 :(得分:1)

单引号需要特殊处理,您可以按以下方式进行引号链接

$ awk '{print gsub(/[!"#$%&'"'"'\(\)*+]/,"")}' 

您也不需要提供第三个参数,默认情况下为$0

答案 2 :(得分:0)

$ awk '{print $0, gsub(/[!"#$%&\047()*+]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

上面的内容在括号表达式中以字符列表列出了您感兴趣的字符,因此将它们视为文字集,使用\047代表',因此它可以在命令行或文件中使用,并使用&作为gsub()的替换,因此它实际上不需要更改您的记录即可变量。

或者可以有一个类似[:punct:]字符类,可以在括号表达式中使用它来替代显式的字符列表< / strong>满足您的需求,例如:

$ awk '{print $0, gsub(/[[:punct:]]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

$ awk '{print $0, gsub(/[^[:alnum:]]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

我在上面用黑体突出显示了正确的POSIX术语。您需要了解的唯一其他相关术语是,您可以在括号表达式中例如指定{strong>字符范围,例如a-z[a-z]

有关括号表达式和字符类/列表/范围的更多信息,请参见the POSIX spec

关于为什么我们使用八进制而不是十六进制表示awk中的单引号,请参见http://awk.freeshell.org/PrintASingleQuote


附录 对于与POSIX标准定义的术语不同的字符集,还有其他用于正则表达式匹配的术语。到目前为止,我已经找到了每个参考文献的以下参考文献:

POSIX RE Standard:

Non-POSIX RE定义:

根据过去30年使用RE的经验和经验,以及人们如何参考RE的各个部分,我创建了一个表格来显示术语上的差异:

  Char Set  |       POSIX Terminology       | Non-POSIX Terminology
------------|-------------------------------|---------------------------
    abc     | Character List                | no specific term
------------|-------------------------------|---------------------------
    a-c     | Character Range               | no specific term
------------|-------------------------------|---------------------------
 [:alpha:]  | Character Class               | POSIX Character Class
------------|-------------------------------|---------------------------
   [...]    | Bracket Expression            | Character List or
            |                               | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
   [abc]    | Bracket Expression containing | Character List or
            | a Character List              | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
   [a-c]    | Bracket Expression containing | Character List or
            | a Character Range             | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
[[:alpha:]] | Bracket Expression containing | Character List or
            | a Character Class             | Character Class or
            |                               | Character Set or
            |                               | Bracket Expression

仅在perl .中也称为字符类(请参见https://perldoc.perl.org/perlrecharclass.html),并且几种工具和工具变体(例如标准UNIX工具的GNU版本)具有POSIX字符类的简写形式,例如与\s的{​​{1}}一样,并具有其他可与字符类相同的转义序列-请查看您的工具手册页。

最好地讲,POSIX术语是清晰,简单且明确的,而其他术语是模棱两可的,因此恕我直言,最好还是坚持使用POSIX术语。