bash awk:在 awk 之外调用函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21794119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:34:30  来源:igfitidea点击:

awk: calling a function outside of awk

bashshellawk

提问by melvynkim

Update:

更新:

I'm working on a modular shell script which calls usage()in different level of subprocess. The script sample.shhas the structure resembles below:

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

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

usage()displays brief information on how to use the script (e.g. available arguments and its descriptions). When executed for the first time, usage()is displayed in the beginning of the script. Examples of other conditions for usage()invocation include:

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

  1. awkfails to validate input from stdioor files

  2. argument--helpis received

  3. other user-derived failures are occurred

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

  2. --help收到论据

  3. 发生其他用户衍生的故障

I'd like to call identical function, usage(), from shell and its direct child process, awk.

我想usage()从 shell 及其直接子进程awk.



Original Question:

原问题:

Function, usage()of sample.shprints its print statement as desired.

函数, usage()ofsample.sh根据需要打印其打印语句。

$cat sample.sh
#!/bin/sh
awk '
    BEGIN {
        usage()
    }
    function usage() {
        print "function inside of awk"
    }
'
$./sample.sh
function inside of awk

To take out usage()from awkand put it as a local function in sample.sh~, I tried:

为了取出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

As we observe, we get the error message saying "undefined function usage" in sample.sh~. How should I improve it?

正如我们所观察到的,我们在sample.sh~. 我应该如何改进它?

回答by BMW

I find a way to call function out of awk

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

put below code in a file, such as call it a.sh

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

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

$ chmod +x a.sh

then you can call the function in awk

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

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

回答by mklement0

With bash, another option is to exportshell functions with export -f, which then become available to awkvia the system()call:

使用bash,另一种选择是使用导出shell 函数export -f,然后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") 
  }'

Note that awkinvokes shwith system(), which may or may not be bash- if it IS bash(e.g., on OSX), you don't strictly need the /usr/bin/env bash -cportion, but leaving it in should make it work on most platforms (that have bash).

请注意,awk调用shwith system(),可能是也可能不是bash- 如果它是bash(例如,在 OSX 上),您并不严格需要该/usr/bin/env bash -c部分,但将其保留在大多数平台(具有 bash)上应该可以工作。

回答by janos

A child process cannot calla function in the parent, and vice versa. Not even in the same language.

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

What you can do, is start another instance of the shell script that contains your awk script. For example, save this in a script called ./script.sh:

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

#!/bin/sh -e

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

test "" = --usage && usage

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

Make it executable, and run as ./script.sh. In this script, the usagefunction inside the inner awkscript simply re-runs the containing shell script with the --usagescript. Keep in mind that there will be 3 processes here: shell -> awk -> shell. It's not possible to do this in a single process.

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

Original answer

原答案

If you move the usagefunction definition outside of awk, then it's normal that you cannot execute from inside. If you want to execute awkcommands you have to be inside of an awkinterpreter, and can only use what is defined inside.

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

Note sure if this is what you're looking for, but you can move the function definition to another awkfile and have awkprocess it, for example:

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

##代码##