【问题标题】:Gawk matching one word - one unexpected matchGawk 匹配一个单词 - 一个意外匹配
【发布时间】:2020-03-06 21:15:50
【问题描述】:

我想获取第 3 列中的所有匹配项,这些匹配项在第 3 列的字符串中具有确切的单词“aa”(不区分大小写的匹配) awk文件中使用的gawk命令为:

$3 ~ /\<aa\>/ 

BEGIN 语句指定:IGNORECASE = 1 该命令返回 20 行。令人费解的是返回行中第 3 列中的这个值:

aA.AHAB

如何避免这一行,因为它本身不是一个单词,因为前两个 aa 后面是点而不是空格?

【问题讨论】:

  • 你所说的“精确词”是什么意思? aA 中的aA.AHAB 是一个整个 词。如果$3 必须等于aa,请使用$3 ~ /^aa$/
  • $3~/^aa$/ 可能有效(未测试)。

标签: awk


【解决方案1】:

A 是一个单词字符。 . 不是单词字符。 \&gt; 匹配单词末尾的零宽度字符串。这样的零宽度字符串出现在A. 之间。

要搜索由空格字符(或行首/行尾)分隔的字符串aa

    $3 ~ /(^|[ ])aa([ ]|$)

在集合中添加您关心的任何其他字符 ([ ])。

请注意,默认情况下,awk 将记录拆分为空格上的字段,因此您不会在 $3 中获得任何空格,除非您更改了 FS 的值。

【讨论】:

  • 成功了。了解上述正则表达式的工作原理及其提供的灵活性。谢谢
【解决方案2】:

第一种解决方案: 或完全匹配 aa 尝试:

awk 'BEGIN{IGNORECASE=1} $3 ~ /^aa$/' Input_file

第二个解决方案: 或者没有IGNORECASE 选项尝试:

awk 'tolower($3)=="aa"' Input_file

【讨论】:

  • IGNORECASE 适用于任何字符串比较和正则表达式匹配。
【解决方案3】:

问题:为什么 awk 正则表达式模式/\&lt;aa\&gt;/ 匹配一个字符串,例如:“aa.bbb”?

我们可以通过以下方式快速验证:

$ echo aa.bbb | awk '/\<aa\>/'
aa.bbb

答案简单在gnu awk的手册中找到:

3.7 gawk 特定的正则表达式运算符

处理正则表达式的 GNU 软件提供了许多额外的正则表达式运算符。这些运算符在本节中进行了描述,并且特定于 gawk;它们在其他 awk 实现中不可用。大多数附加运算符处理单词匹配。就我们而言,单词是一个或多个字母、数字或下划线 ('_') 的序列

  • \&lt;: 匹配单词开头的空字符串。例如,/\&lt;away/ 匹配 "away" 但不匹配 "stowaway"
  • \&gt;: 匹配 word 末尾的空字符串。例如,/stow\&gt;/ 匹配 "stow" 但不匹配 "stowaway"

来源:GNU awk manual: Section 3 :: Regular Expressions

所以回到上面的例子,字符串“aa.bbb”包含两个单词“aa”和“bbb”,因为字符不是可以构建单词。这里匹配的空字符串是“aa.bbb”之前的空字符串和字符a.之间的空字符串(空字符串是真正的空字符串,长度为0、0个字符,一般写成@987654334 @)

OP 的解决方案:由于FS 很可能是默认值,所以字段$3 不能有空格。所以以下两种解决方案是可能的:

 $3 ~ /^aa$/
 $3 == "aa"

如果在代码中定义了字段分隔符FS,以下可能会起作用

" "$3" " ~ /" aa "/
$3 ~ /(^|[ ])aa([ ]|$)       # See solution of JHNC

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2017-02-10
    相关资源
    最近更新 更多