在Mac OS X上使用awk精确匹配单词

3

尝试在Mac OS X上使用awk。一个例子:

$ echo "abc stock def" | awk /stock/ 
abc stock def
$ echo "abc stockholder def" | awk /stock/
abc stockholder def

当我尝试使用awk进行单词精确匹配时,遇到了麻烦。例如,我想仅匹配上面例子中的stock而不是stockholder。我尝试过使用\<\>\b\y,但它们都没有给我预期的结果。

谢谢


2
为什么要使用awk| grep -w "stock" 这样做就行了。 - fedorqui
1
我知道我可以使用grep。但是,我需要使用awk来处理跨越所有行的文件。正则表达式匹配只是第一步。谢谢。 - Lszomb
如果您只想匹配“stock”,那么在“stock”前后留一个空格即可。现在,它只会将“stock”作为完整的单词进行匹配。 echo "abc stock def" | awk / stock / - user3442743
1
@Lszomb,您的字符串中单词的位置是否很重要?如果是第二个单词,那么可以这样写:awk '$2 == "stock"' - fedorqui
@fedorqui:不对,这个词可以出现在字符串的任何位置。我需要从一个字符串中找到确切的字符串"stock"。 - Lszomb
显示剩余2条评论
4个回答

4
您可以像这样使用正则表达式:
$> echo "abc stock def" | awk '/(^| )stock( |$)/'
abc stock def

$> echo "abc restock def" | awk '/(^| )stock( |$)/'
$>

更新: 如果要匹配除了空格和起始/结束锚点以外的更多边界,请使用以下正则表达式:

$> echo "abc-stock-def" | awk '/[^[:alnum:]]stock[^[:alnum:]]/'
abc-stock-def

$> echo "abc-stocks-def" | awk '/[^[:alnum:]]stock[^[:alnum:]]/'
$> 

我还在我的Mac上通过homebrew安装了gnu-awk,使用它可以执行以下操作:

echo "abc stock def" | gawk '/\<stock\>/'
abc stock def

$> echo "abc restock def" | gawk '/\<stock\>/'
$>

3
如果它始终处于第二个位置,您可以使用以下方法:
awk '$2 == "stock"'

如果可以在任何位置使用,则使用:

awk '{for (i=1;i<=NF;i++) if ($i == "stock") {print; next}}'

请看以下示例:

$ echo "abc stock stock def" | awk '{for (i=1;i<=NF;i++) if ($i == "stock") {print; next}}'
abc stock stock def

$ echo "abc stockd def" | awk '{for (i=1;i<=NF;i++) if ($i == "stock") {print; next}}'
$

感谢您的回答。从编程和技术角度来看,这是完美的。然而,我很想了解为什么在Mac OS X上,BSD和GNU版本的正则表达式匹配都无法在awk中工作。如果没有人提供正则表达式版本,我将接受您的答案。 - Lszomb
如果比较的是固定字符串,我认为您不需要使用正则表达式。 - fedorqui

1
一个典型的单词组成字符的定义(例如GNU awk中的\w)是任何字母数字或下划线,因此:
$ cat file
abc stock def
abc stock. def
abc stockholder def
abc stock
stock def

$ awk '/(^|[^[:alnum:]_])stock([^[:alnum:]_]|$)/' file
abc stock def
abc stock. def
abc stock
stock def

[:alnum:]_ 更改为您的定义,如果不是这样的话。

1
POSIX 定义了 [[:<:]][[:>:]] 作为单词边界。我在我的 Mac 上尝试了一下,但没有输出。我强制使用 --posix 选项,结果仍然相同。awk 是否使用自己的正则表达式呢? - jaypal singh
我从未听说过这些字符类,坦白地说,我不相信,我认为你所提到的网站是错误的,但我愿意接受纠正。有人能指出定义这个的POSIX规范吗? - Ed Morton
@jaypal:实际上,[[:<:]][[:>:]]在OSX上与sed一起使用效果很好,但奇怪的是awk不支持它们。 - anubhava
我毫不怀疑这些结构在某些工具中存在且可用,只是我不相信它们是POSIX标准。声称它们是POSIX标准的网站存在其他问题,并似乎试图描述可以出现在所有工具中的所有可能的结构,这很好,但它并没有很好地识别哪些结构与哪个工具或标准相关。 - Ed Morton
1
我在http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html找到了最新的POSIX字符类(2013年),但没有提到“[[:<:]]”。 - Ed Morton

0

我倾向于使用以下方法(也适用于不支持正则表达式的语言):

echo " abc stock def " | grep ' stock '
echo " stock abc def " | grep ' stock '
echo " abc def stock " | grep ' stock '

请注意输入和模式开头和结尾的空格。
在这里,解析器(例如此示例中的grep)不需要正则表达式支持。甚至C的标准函数strstr也可以匹配这个...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接