在Bash中使用Awk进行命令替换

3
为什么这个能够工作:
这个。
var=hello
myvar=`echo hello hi | awk "{ if (\\\$1 == \"$var\" ) print \\\$2; }"`
echo $myvar

提供

hi

但这并不是这样的吗?

这个

var=hello
echo hello hi | awk "{ if (\\\$1 == \"$var\" ) print \\\$2; }"

提供

awk: cmd. line:1: Unexpected token

我正在使用

GNU bash 4.1.5(1)发布版(i486-pc-linux-gnu版本)

Linux 2.6.32-34-generic-pae #77-Ubuntu SMP Tue Sep 13 21:16:18 UTC 2011 i686 GNU/Linux


你可以尝试这两段代码。第二段会出现错误。 - Ankur Agarwal
6
这不是 Stack Overflow 的运作方式。一个良好的问题应该包括你的目标以及未达到期望结果的解释。人们可能会尝试你的代码,但完整地解释你的问题是由你来完成的。 - Jim Garrison
好的,我编辑了我的问题并添加了我得到的输出。 - Ankur Agarwal
1
我得到了一个不同的错误:反斜杠不是行中的最后一个字符。在您的命令之前尝试使用set -x,在命令之后使用set +x,以查看变量替换和反斜杠评估等操作的跟踪。 - Dennis Williamson
2个回答

11

正确的将shell变量传递到AWK程序中的方法是使用AWK的变量传递功能,而不是尝试嵌入shell变量。通过使用单引号,你就不必进行大量不必要的转义。

echo "hello hi" | awk -v var="$var" '{ if ($1 == var ) print $2; }'

此外,你应该使用$()而不是反引号。


谢谢Dennis。你是对的,我知道awk -v。但是我想知道为什么我的第二次尝试失败了。 - Ankur Agarwal
@abc:处理复杂的引用和转义以及正确使用反引号是一个棘手的问题。一开始就正确地处理可以避免所有不愉快的情况。当我运行你的第一个示例时,我没有得到错误,但也没有输出回显该变量。 - Dennis Williamson
Dennis,我添加了我使用的bash版本和Linux版本。对我来说,它很好地工作。你使用的是哪个版本? - Ankur Agarwal
@abc:抱歉,命令替换确实可行。在我的测试中,我将var设置为了错误的值。 - Dennis Williamson

5
如果你的awk和我的一样,它会告诉你失败发生的位置:
var=hello
echo hello hi | awk "{ if (\\\$1 == \"$var\" ) print \\\$2; }"

awk: syntax error at source line 1
 context is
    { if >>>  (\ <<< $1 == "hello" ) print \$2; }
awk: illegal statement at source line 1

此外,如果您将awk替换为echo,您就会清楚地看到它为什么失败。
echo hello hi | echo "{ if (\\\$1 == \"$var\" ) print \\\$2; }"
{ if (\$1 == "hello" ) print \$2; }

在生成的命令中有额外的 '\' (反斜杠)。这是因为您删除了反引号。所以解决方案是删除一对 '\'。

echo hello hi | awk "{ if (\$1 == \"$var\" ) print \$2; }"
hi

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