【问题标题】:Dereferencing variables in awk在 awk 中取消引用变量
【发布时间】:2013-05-04 17:19:03
【问题描述】:

为什么这不起作用?

x=5
$ ls -l | awk '{print $(($x))}'

应该打印 ls -l 命令的字段 5,对吗?

【问题讨论】:

  • awk 不是外壳,就像 C 不是外壳一样。您不应该期望在 awk 程序中使用 shell 变量或语言结构,就像在 C 程序中使用它们一样。

标签: variables awk dereference


【解决方案1】:

应该将shell变量的值传递给awk的唯一方法如下

$ x=5

$ ls -l | awk -v x="$x" '{print $x}'

$ ls -l | awk '{print $x}' x="$x"

这两种方法的主要区别在于,通过使用-vx 的值在BEGIN 块中设置,而第二种方法不会设置该值。除非您喜欢头痛,否则不应使用所有其他带有引用技巧或转义的方法不应


但是你不想根本不想解析ls,你真正想要的命令是:

stat --printf="%s\n" *

假设您的ls 的第五列与我的相同,这将显示当前目录中的所有文件大小。

【讨论】:

    【解决方案2】:

    您可以访问类似于这些的 shell 变量;

    不建议第一种方式!

    x=5
    ls -l | awk '{print $'$x'}'
    

    或在程序开始执行之前将值 x 赋给变量 shellVar

    x=5
    ls -l | awk -v shellVar="$x" '{print $shellVar}'
    

    或使用包含当前环境值的数组

    export x=5
    ls -l | awk '{print $ENVIRON["x"]}'
    

    【讨论】:

    • 永远不要做上面的第一个,否则你会因为变量“x”的各种内容而得到令人讨厌的惊喜。有关所有替代方案的讨论,请参阅 cfajohnson.com/shell/cus-faq-2.html#Q24
    【解决方案3】:

    这是一个shell变量,它不是由单引号中的shell扩展的。我们将 awk 脚本放在单引号中的原因正是为了防止 shell 解释为 awk 的利益而设计的东西并把事情搞砸,但有时您希望 shell 解释它的一部分。

    对于这样的事情,我更喜欢将值作为 awk 变量传递:

    ls -l | awk -v "x=$x" '{print $x}'
    

    但你可以做任何其他方式。例如,这个:

    ls -l | awk '{print $'$x'}'
    

    应该是这样的:

    ls -l | awk '{print $'"$x"'}'
    

    或者,这个:

    ls -l | awk "{print \$$x}"
    

    【讨论】:

    • 只有上面的第一个接近成为一个有效的选项(应该是-v x="$x",其余的不要做。有关所有替代方案的讨论,请参阅cfajohnson.com/shell/cus-faq-2.html#Q24
    • 关闭? -v x="$x"-v "x=$x"awk 完全无法区分,它们在每种情况下都从 shell 接收完全相同的参数字符串。我也可以使用-'v' "x"'='"$x" 或大量其他组合中的任何一种。
    • 这具有误导性,因为 -v "x=$x" 看起来您正在将字符串 "x=$x" 传递给程序以设置 -v 指示的变量,就像 -F "x=$x" 设置变量 FS 到字符串“x=$x”,而-v x="$x" 非常清楚地将"$x" 的值分配给变量x。没错,您可以使用任何其他组合或更多组合,它们也会混淆您的代码。保持简单明了:variable="value".
    • 很公平。我在 Awk 风格的比赛中没有马,无论如何,我们对 SO 上的 cmets 投入了太多。我纯粹是从 shell 的角度来看它,我发现 x="$x" 更具误导性;它看起来像一个 shell 分配,但它不是(虽然它会被解释为set -o keyword 下的一个,但我不知道有谁使用该选项集运行)。我只是发现将分组引号一直放在被分组的单词的外部会更清楚。
    【解决方案4】:

    试试这个:

    ls -l | awk '{print $'$x'}'
    

    【讨论】:

    猜你喜欢
    • 2019-01-17
    • 2019-08-19
    • 1970-01-01
    • 2013-11-28
    • 2014-10-15
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多