【问题标题】:Handling arbitrary arguments portably in AWK在 AWK 中可移植地处理任意参数
【发布时间】:2016-03-09 22:24:20
【问题描述】:

我想让我的 shebang 启用 POSIX awk 程序有更多的标准接口 - 不使用 -v var=val 接口,而是使用看起来像 Linux/UNIX 命令行中可用的其他程序。我遇到的问题是 awk 脚本将标志中继到 awk ——然后 awk 本身首先破解了这些标志。此外,awk 的不同实现有不同的标志选项。最终的结果是,几乎不可能构建一个 awk 程序,其接口只能用于解析 ARGC、ARGV[] 以获取标志。

所以,我最终将我的 awk 程序封装在 shell 中——这增加了我的支持和测试负担——并且 shell 代码如下所示:

arg_core=""
arg_directory=""
arg_module=""
arg_output=""
arg_regmap=""
arg_regpage=""
arg_help=0
arg_version=0
arg_verbose=0
while getopts c:d:m:o:p:r:hvV o
do
        case "$o" in
        c) arg_core="$OPTARG";;
        d) arg_directory="$OPTARG";;
        m) arg_module="$OPTARG";;
        o) arg_output="$OPTARG";;
        p) arg_regpage="$OPTARG";;
        r) arg_regmap="$OPTARG";;
        h) arg_help=1;;
        v) arg_version=1;;
        V) arg_verbose=1;;
        --) break;;
        ?) help >&2
             exit 1;;
        esac
done
shift `expr $OPTIND - 1`

# Handling help and version (verbose option also displays revision
# history and notes) is more easily done outside the getopts loop.
if [ $arg_version -gt 0 ]
then
        version
        [ $arg_verbose -gt 0 ] && rev_history
fi
if [ $arg_help -gt 0 ]
then
        [ $arg_version -gt 0 ] && echo
        help
fi
[ $arg_help -gt 0 -o $arg_version -gt 0 ] && exit 0

awk -v arg_core="$arg_core" -v arg_directory="$arg_directory" -v arg_module="$arg_module" -v arg_output="$arg_output" -v arg_regmap="$arg_regmap" -v arg_regpage="$arg_regpage" -f rffe2tpf.awk -- "$@"

我的问题是...我想消除 shell 脚本封装并希望在 awk 中进行我的参数解析——并且我想可移植地 这样做。 (注意...我不是在问,“我如何在 awk 中执行 getopts?”而是在问,“我如何在 >awk 脚本可移植地阻止 awk 解析标志?”)有没有办法欺骗 awk 或 shebang 实现这个目标?

【问题讨论】:

  • GNU awk 执行have a getop function。这是你需要的吗?
  • @BinaryZebra -- portable 对我来说意味着我想符合 POSIX。目前,我希望可以选择使用 gawk 或 mawk...而且我还希望我的脚本能够相对面向未来。
  • 来自非 gnu 的 awk getopt 不可用 AFAIK。 POSIX getopts 仅适用于 shell 脚本。你进入了一个受伤的世界。祝你好运。
  • 这就是我使用 perl 的原因
  • 我不明白为什么对 GNU 的自动响应是:“不是 POSIX”,事实上,在大多数程序中都有很多 POSIX 合规性工作。好吧,我想这是宇宙中未解之谜之一。

标签: linux shell unix awk posix


【解决方案1】:

发布到 stackoverflow 让我对这个问题有了更深入的思考,我相信我有更接近解决方案的东西。如果有人有一些我不知道的“shebang-foo”可以解决这个问题,那么我会选择我自己的答案。

特别感谢 BinaryZebra 将我指向 getopt.awk -- 因为我不再需要考虑推出自己的 getopt() 实现。

我们可能无法通过 shebang 以可移植的方式提供我们想要的行为,但我们能够显着限制 shell 脚本中的代码量以支持我们想要的行为。建议的解决方案是通用的,可用于我们所有的 awk 脚本。

我将以下脚本称为 bawk

#! /usr/bin/env sh
p=$1
shift
awk -f "$p" -- "$@"

如果 bawk 放在我们的路径中,则可以在 awk 脚本的 shebang 中使用。这是一个测试脚本:

#! /usr/bin/env bawk
BEGIN { for (i=1; i<ARGC; i++) print ARGV[i] }

输出:

$ ./foo.awk -abc -1 -2 -3
-abc
-1
-2
-3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多