使用 GNU awk

使用 GNU awk

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

#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }

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

答案1

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

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

$ ./tst.sh
Executing: ./tst.sh

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

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

$ ./tst2.sh
Executing: ./tst2.sh

最后一个可以与任何平台上任何 shell 中的任何现代 awk 一起使用。

答案2

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

呆呆地

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

cmdname.awk

#!/usr/bin/gawk -f

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

莫克和诺克

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

cmdname.awk

#!/usr/bin/mawk -f

BEGIN { 
  ("ps -p $PPID -o comm=") | getline CMDNAME
  print CMDNAME
}

测试

像这样运行脚本:

./cmdname.awk

两种情况下的输出:

cmdname.awk

答案3

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

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

linux可以尝试使用一种肮脏的黑客方法,正如评论中指出的那样斯蒂芬·查泽拉斯awk如果实现支持 NUL 字节是可能的:

#!/usr/bin/awk -f

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

答案4

使用 GNU awk

检查GNU awk 用户指南 - 7.5.2 传递信息的内置变量我偶然发现:

程序信息#

该数组的元素提供对正在运行的 awk 程序的信息的访问。以下元素(按字母顺序列出)保证可用:

PROCINFO["pid"]

当前进程的进程ID。

这意味着你可以在运行时知道程序的PID。然后,需要使用system()这个给定的 PID 来查找进程:

#!/usr/bin/gawk -f
BEGIN{ pid=PROCINFO["pid"]
       system("ps -ef | awk '$2==" pid " {print $NF}'")
}

我使用ps -ef,它在第二列上显示 PID。假设执行完成awk -f <script>并且没有其他参数,我们可以假设该行的最后一个字段包含我们想要的信息。

如果我们有一些参数,我们将不得不以不同的方式解析该行 - 或者,更好的是,使用一些选项来ps仅打印我们感兴趣的列。

测试

$ awk -f a.awk 
a.awk
$ cp a.awk hello.awk
$ awk -f hello.awk 
hello.awk

另请注意,GNU awk 用户指南的另一章告诉我们 ARGV 不是正确的选择:

1.1.4 可执行的 awk 程序

最后,ARGV[0] 的值(请参阅内置变量)根据您的操作系统而变化。有些系统在那里放置“awk”,有些系统放置 awk 的完整路径名(例如 /bin/awk),有些系统放置脚本的名称(“advice”)。 (直流)不要依赖 ARGV[0] 的值来提供脚本名称。

相关内容