【问题标题】:command substitution in bash with awk用 awk 替换 bash 中的命令
【发布时间】:2012-05-08 04:12:13
【问题描述】:

为什么会这样:

这个

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)-release (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

【问题讨论】:

  • 你可以试试这两个代码。您将看到第二个错误。
  • 这不是 SO 的工作方式。格式良好的问题包括对您的目标的解释以及不符合您期望的结果。人们可能会尝试您的代码,但您需要完全解释您的问题。
  • 好的,我编辑了我的问题并添加了我得到的输出。
  • 我得到一个不同的错误:backslash not last character on line。在命令之前尝试set -x,在命令之后尝试set +x,以查看变量替换和反斜杠评估等工作原理。
  • @DennisWilliamson Ok 会尝试的。谢谢。

标签: linux bash


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢丹尼斯。你是对的,我知道 awk -v。但我想了解为什么我的第二次尝试实际上失败了。
  • @abc:复杂的引用和转义以及正确使用反引号是一个棘手的命题。首先正确地执行它可以避免所有这些不愉快。当我运行您的第一个示例时,我没有收到错误消息,但也没有得到任何与变量相呼应的输出。
  • Dennis,我添加了我正在使用的 bash 版本和 Linux 版本。它对我来说很好。你用的是什么版本?
  • @abc:抱歉,命令替换确实有效。在我的测试中,我将 var 设置为错误的值。
【解决方案2】:

如果你的 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; }

生成的命令中有额外的“\”(反斜杠)。这是因为您删除了反引号。 所以解决办法就是去掉一对\'s

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

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    相关资源
    最近更新 更多