awk:警告:在 Mac OSX 终端中运行命令时,转义序列“\/”被视为普通“/”错误

use*_*627 2 awk

我目前正在查看一些适用于 Linux 系统(我使用的是 Mac)的代码,并一直在尝试运行这一awk行:

awk -F"[:,}][^:\/\/]" '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/)
{print $(i+1)}}}' | tr -d '"' | sed -n ${num}p | sed -e 
's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/[,]*$//'
Run Code Online (Sandbox Code Playgroud)

返回以下错误:

awk: warning: escape sequence `\/' treated as plain `/'.
Run Code Online (Sandbox Code Playgroud)

我了解某些实现和语法与 Mac 和 Linux 不同。这个错误可能是其中之一吗?谢谢。

Ed *_*ton 5

一个最小的例子:

$ awk -F"[:,}][^:\/\/]" '1' /dev/null
awk: warning: escape sequence `\/' treated as plain `/'
Run Code Online (Sandbox Code Playgroud)

修复:

$ awk -F'[:,}][^://]' '1' /dev/null
$
Run Code Online (Sandbox Code Playgroud)

即没有理由在动态正则表达式中转义正斜杠。您必须在正则表达式文字中转义它们(例如/foo\/bar/),因为它们是正则表达式分隔符,而不是因为它们是正则表达式元字符,因此动态正则表达式中的情况并非如此(存储在字符串中,因此由字符串分隔)分隔符,而不是正则表达式分隔符)。我还修正了你的报价。

/但请注意,在括号表达式中重复相同的字符(例如)是没有用的。与或[/]完全相同的字符集。[//][///////]

如果你确实必须逃避的话/那就是:

$ awk -F'[:,}][^:\\/]' '1' /dev/null
$
Run Code Online (Sandbox Code Playgroud)

如果您在原始代码中使用了错误的引号:

$ awk -F"[:,}][^:\\\/]" '1' /dev/null
$
Run Code Online (Sandbox Code Playgroud)

在 - 分隔字符串中需要进行 2 次转义',因为 awk 必须先将字符串转换为正则表达式(解析第 1 步),然后再将其用作正则表达式(第 2 步)。

在 - 分隔的字符串中需要 3 次转义",因为在这种情况下,您专门告诉 shell 解析该字符串,因此 shell 必须先解析它(传递 1),然后再将其传递给 awk,然后 awk 必须将字符串转换为正则表达式(第 2 步),然后将其用作正则表达式(第 3 步)。

顺便说一句,脚本的其余部分错误地使用了 shell 变量。这:

awk -F'[:,}][^:/]' '{for(i=1;i<=NF;i++){if($i~/\042'$KEY'\042/)
Run Code Online (Sandbox Code Playgroud)

如果可以让 shell 变量扩展成为 awk 脚本文本的一部分(但事实并非如此),则可以写为:

awk -F'[:,}][^:/]' '{for(i=1;i<=NF;i++){if($i~/\042'"$KEY"'\042/)
Run Code Online (Sandbox Code Playgroud)

但正确的方法是:

awk -F'[:,}][^:/]' -v key="$KEY" '{for(i=1;i<=NF;i++){if($i~"\042"key"\042")
Run Code Online (Sandbox Code Playgroud)

或者最好是:

awk -F'[:,}][^:/]' -v key="\"$KEY\"" '{for(i=1;i<=NF;i++){if($i~key)
Run Code Online (Sandbox Code Playgroud)