awk:在awk之外调用一个函数

时间:2014-02-15 06:15:08

标签: bash shell awk

更新

我正在开发一个模块化shell脚本,它在不同级别的子进程中调用usage()。脚本sample.sh的结构类似于:

sample.sh
├─ ...
├─ usage()
├─ awk
    ├─ usage()
├─ ...

usage()显示有关如何使用脚本的简要信息(例如,可用参数及其描述)。第一次执行时,脚本开头会显示usage()usage()调用的其他条件示例包括:

  1. awk无法验证来自stdio或文件的输入

  2. 收到
  3. 参数--help

  4. 发生了其他用户派生的故障

  5. 我想从shell及其直接子进程usage()调用相同的函数awk


    原始问题:

    usage()的{​​{1}}函数根据需要打印其print语句。

    sample.sh

    要从$cat sample.sh #!/bin/sh awk ' BEGIN { usage() } function usage() { print "function inside of awk" } ' $./sample.sh function inside of awk 中取出usage()并将其作为awk中的本地函数,我尝试了:

    sample.sh~

    正如我们所观察到的,我们在$cat sample.sh~ #!/bin/sh usage() { print "function outside of awk" } awk ' BEGIN { usage() } ' $./sample.sh~ awk: calling undefined function usage source line number 3 中收到错误消息“未定义的函数用法”。我应该如何改进它?

3 个答案:

答案 0 :(得分:4)

我找到了一种从awk调用函数的方法

将下面的代码放在一个文件中,例如将其命名为a.sh

$ cat a.sh
usage() {
  print "function outside of awk"
 }

$ chmod +x a.sh

然后你可以在awk中调用函数

#!/bin/sh
awk '
    BEGIN {
       system(". a.sh;usage")
    }'

答案 1 :(得分:2)

子进程无法调用父进程中的函数,反之亦然。甚至不是同一种语言。

您可以做的是启动包含您的awk脚本的shell脚本的另一个实例。例如,将其保存在名为./script.sh的脚本中:

#!/bin/sh -e

usage() {
    echo usage: ...
    exit 1
}

test "$1" = --usage && usage

awk -v usage_script="$0" '
function usage() { system(usage_script " --usage") }
BEGIN {
    usage()
}'

使其可执行,并以./script.sh运行。在此脚本中,内部usage脚本中的awk函数只需使用--usage脚本重新运行包含的shell脚本。请记住,这里将有3个进程:shell - > awk - >贝壳。在一个过程中无法做到这一点。

原始回答

如果将usage函数定义移到awk之外,则无法从内部执行是正常的。如果要执行awk命令,则必须在awk解释器中,并且只能使用内部定义的内容。

请注意确定这是否是您要查找的内容,但您可以将函数定义移至另一个awk文件并对awk进行处理,例如:

cat <<EOF > functions.awk
function usage() {
    print "function in functions.awk"
}
EOF
awk -f functions.awk -e '
    BEGIN {
        usage()
    }
'

答案 2 :(得分:2)

使用bash,另一个选项是使用export -f 导出 shell函数,然后通过awk调用将system()提供给#!/usr/bin/env bash usage() { echo "function outside of awk" } # Export the usage() function. export -f usage awk ' BEGIN { system("/usr/bin/env bash -c usage") }'

awk

请注意,sh调用system() bashbash可能是/usr/bin/env bash -c - 如果是{{1}}(例如,在OSX上),你并不严格需要{{1}}部分,但保留它应该使它适用于大多数平台(有bash)。