如何在mawk中打​​印自己的脚本名称?

cip*_*per 14 scripting awk mawk

在 bash 中$0包含脚本的名称,但在 awk 中,如果我使用以下内容创建一个名为 myscript.awk 的脚本:

#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }
Run Code Online (Sandbox Code Playgroud)

并运行它,它只会打印“awk”。此外,带有 i>0 的 ARGV[i] 仅用于命令行中的脚本参数。那么,如何让它打印脚本的名称,在这种情况下是“myscript.awk”?

Tho*_*hor 6

我不知道从 awk 中获取命令名称的任何直接方法。但是,您可以通过子外壳找到它。

呆呆的

使用 GNU awk 和ps命令,您可以使用进程 IDPROCINFO["PID"]来检索命令名称作为解决方法。例如:

cmdname.awk

#!/usr/bin/gawk -f

BEGIN {
  ("ps -p " PROCINFO["pid"] " -o comm=") | getline CMDNAME
  print CMDNAME
}
Run Code Online (Sandbox Code Playgroud)

mawk 和 nawk

您可以使用相同的方法,但从特殊的 shell 变量(父级的 PID)派生awk的 PID $PPID

cmdname.awk

#!/usr/bin/mawk -f

BEGIN { 
  ("ps -p $PPID -o comm=") | getline CMDNAME
  print CMDNAME
}
Run Code Online (Sandbox Code Playgroud)

测试

像这样运行脚本:

./cmdname.awk
Run Code Online (Sandbox Code Playgroud)

两种情况下的输出:

cmdname.awk
Run Code Online (Sandbox Code Playgroud)


Ed *_*ton 6

在 cygwin 上的 bash 中使用 GNU awk 4.1.3:

$ cat tst.sh
#!/bin/awk -f
BEGIN { print "Executing:", ENVIRON["_"] }

$ ./tst.sh
Executing: ./tst.sh
Run Code Online (Sandbox Code Playgroud)

我不知道这有多便携。不过,与往常一样,我不会在 shell 脚本中使用 shebang 执行 awk 脚本,因为它只会剥夺您可能的功能。保持简单,只需这样做:

$ cat tst2.sh
awk -v cmd="$0" '
BEGIN { print "Executing:", cmd }
' "$@"

$ ./tst2.sh
Executing: ./tst2.sh
Run Code Online (Sandbox Code Playgroud)

最后一个适用于任何平台上任何 shell 中的任何现代 awk。

  • 谢谢!`ENVIRON["_"]` 完美运行,它不调用任何外部程序。第二个选项 `awk -v ...` 取决于运行脚本的方式;我不要这个。 (2认同)
  • 将您的脚本称为“tst.sh”会产生误导。这是一个“awk”脚本,而不是 shell 脚本。“BEGIN”不是有效的 shell 命令。 (2认同)

tal*_*zin 5

根据gawk 文档,我认为这是不可能的:

最后,ARGV[0](参见第 7.5 节内置变量)的值因您的操作系统而异。有些系统放在awk那里,有些是 awk 的完整路径名(例如/bin/awk),有些是你的脚本名称('advice')。不要依赖 的值ARGV[0]来提供您的脚本名称。

linux你可以尝试使用一种肮脏的黑客的并且在评论中指出斯特凡Chazelas这是可能的,如果实施的awk支持NUL字节:

#!/usr/bin/awk -f

BEGIN { getline t < "/proc/self/cmdline"; split(t, a, "\0"); print a[3]; }
Run Code Online (Sandbox Code Playgroud)


cuo*_*glm 5

使用 POSIX awk

#!/usr/bin/awk -f

BEGIN {
    print ENVIRON["AWKSCRIPT"]
}
Run Code Online (Sandbox Code Playgroud)

然后:

AWKSCRIPT=test.awk ./test.awk
test.awk
Run Code Online (Sandbox Code Playgroud)

  • 您手动将脚本的名称输入其中,这不是自打印方式 (6认同)
  • 这就像调用`awk -vNAME =“myscript.awk”./myscript.awk`,然后在脚本中打印变量“NAME”。不是解决方案。 (5认同)