【问题标题】:Passing Bash argument into Bash Variable encapsulating AWK Command将 Bash 参数传递给封装 AWK 命令的 Bash 变量
【发布时间】:2014-09-13 03:57:37
【问题描述】:

我需要能够运行脚本并传递参数(日期和月份),例如

$root# ./myscript -v 31 12

但我似乎找不到任何合适的方法来将命令行参数传递给 bash 变量 X 中的 awk 命令,而不会导致脚本阻塞。我尝试使用双引号来允许变量插值,使用 Stack Overflow 上其他地方概述的反斜杠转义其他美元符号,但无济于事。

#!/bin/bash
X=$(./some_script | awk -v VARIABLE="$1" '$1 == "VARIABLE" | awk '{print $1,$2,$3}')
Y=$(./other_script | awk -v VARIABLE="$2" '$1 == "VARIABLE" | awk '{print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

这会阻塞脚本并返回错误

awk: syntax error near line 1 
awk: bailing out near line 1

已解决 似乎标准的 Solaris 'AWK' 不接受 -v 标志,并且该特定错误在某种程度上传达了它。用 nawk 切换它,它运行良好,如下所述。 @David_W 详细介绍了 nawk/awk 参数传递。非常感谢 @Ed_Morton 发现错误,感谢 @anubhava 和 @hek2mgl 进行概念验证。

#!/bin/bash
echo
X=$(./some_script | nawk -v VARIABLE="$1" '$1 == "VARIABLE" {print $1,$2,$3}')
X=$(./other_script | nawk -v VARIABLE="$1" '$1 == "VARIABLE" {print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

【问题讨论】:

  • 为了清楚起见,感谢贡献者。

标签: linux bash shell awk solaris


【解决方案1】:

根据awk的版本,有两种将环境变量传递到awk的方法:

awk 的较新版本(在 Solaris 系统上有时称为 nawk):

$ awk -v var1="$var1" -v var2="$var2" prog.awk

老版本的 awk 让你在最后设置变量:

$ awk prog.awk var1="$var1" var2="$var2"

我不能 100% 确定最后一个是否完全按照它的方式完成。我已经有 20 多年没有使用过旧版本的 awk 了。甚至 Solaris 也允许您通过调用nawk 或使用/usr/xpg4/bin 中的awk 来使用较新版本的awk(我建议将$PATH 放在/bin/usr/bin 之前。这样,来自其他操作系统(如 Mac OS X 和 Linux)的 shell 脚本更有可能以兼容的方式工作。)

来自 Solaris XPG4(第 5 节)联机帮助页:

如果 POSIX.2、POSIX.2a、XPG4、SUS 或 SUSv2 要求的行为与历史 Solaris 实用程序行为冲突,则该实用程序的原始 Solaris 版本保持不变; /usr/xpg4/bin 中提供了符合标准的新版本。对于希望利用 POSIX.2、POSIX.2a、XPG4、SUS 或 SUSv2 功能的应用程序,应设置 PATHshksh)或 pathcsh)环境变量/usr/xpg4/bin 位于可以找到这些规范指定的实用程序的任何其他目录之前,例如 /bin/usr/bin/usr/ucb/usr/ccs/bin

【讨论】:

  • FYI nawk (for New AWK) 是一个很好的例子,说明为什么你不应该在任何软件的名称中使用 New 这个词,因为它现在已经过时并且缺乏更现代的 awks 的功能. nawk 比旧的、损坏的 awk 好得多,但 /usr/xpg4/bin/awk 比 nawk 好,gawk 比任何其他可用的 awk 都要好一英里。
  • 原版awk 由 AT&T 于 1977 年编写。 BSD 在工作方式上几乎保持了相同的awk。 (BSD 是 Solaris 所基于的 Unix 版本)。 1980 年代,AT&T 重写了awk,并将新版本命名为nawk。当 Unified Unix 标准创建时,nawk 成为标准 awk。 SunOS 和更高版本的 Solaris 将 awk 的原始 BSD 版本保留在其标准程序目录中以实现兼容性。我不知道nawk/usr/xpg4/bin/awk 之间是否有区别以及操作方式。不要让我开始使用 gawk 和这些实用程序的其他 GNU 版本。
  • nawk 支持大部分 POSIX 功能,/usr/xpg4/bin/awk [几乎] 支持所有 POSIX 功能,gawk 支持所有 POSIX 功能以及一些非常有用的扩展。
【解决方案2】:

您可以使用awk -v name=val 将参数从shell 传递给awk

试试这个:

#!/bin/bash
X=$(./some_script | awk -v val="HARDCODED" '$1 == val {print $1,$2,$3}')
Y=$(./some_other_script | awk -v val="HARDCODED" '$1 == val {print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

【讨论】:

  • 现有的 awk 命令没有任何问题,您的回答中也没有解决问题。
  • 好吧,让我们谈谈问题。您写道:我似乎找不到任何合适的方式将命令行参数传递给 awk 命令您究竟在脚本的哪个位置将参数传递给 awk?我只能猜测您正在尝试传递某些东西来代替 HARDCODED,但您确实需要澄清它。
  • @LazyJim 请放轻松。你不是这里的老板。你只是在寻求帮助。
  • OP 最终发布了他在@hex2mgls 答案下的评论中收到的错误消息,它告诉我们他使用的是旧的、损坏的 awk。一旦他切换到现代 awk,他会没事的。
  • 啊,对了,我刚读了。那个旧的 solaris awk 肯定不会处理这个 -v 选项
猜你喜欢
  • 2016-05-31
  • 2017-06-15
  • 1970-01-01
  • 2021-11-25
  • 2014-12-04
  • 2019-06-22
  • 2015-01-08
  • 2015-02-15
相关资源
最近更新 更多