gawk 通常在 /bin 或 /usr/bin 中吗?我会同意#!/usr/bin/env gawk
,但我不能使用参数。现在我正在使用#!/bin/gawk -f
.该脚本非常长,包含大量单引号,并且适用于标准输入。
GNU Awk 手册有1.1.4 可执行 awk 程序它在示例中使用 #!/bin/awk 但接着说:
请注意,在许多系统上
awk
可能会找到 in/usr/bin
而不是 in/bin
。买者自负。
大多数人做什么?我读了sed 据称在 /bin 中标准化而 perl 据说在 /usr/bin 中标准化(与 sed 链接相同的页面,但他们不允许我为这篇文章创建第三个链接)。 awk/gawk 怎么样?有谁知道哪个更常见或流行?
答案1
如果您不需要向命令传递参数,那么这#!/usr/bin/env gawk
是可行的方法,但是许多内核(包括 Linux)只接受 shebang 程序的单个参数。
否则,你可以做一个多语言程序既是 shell 包装器又是 awk 脚本。这是 awk 的一个。
#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here
外壳解析:
true + /;
— 带有两个惰性参数的命令true
(不执行任何操作)+
和/
。- 呼叫到
gawk
.这可以是任何不包含换行符且写入斜杠的 shell 片段\/
(除了内部引号外,shell 不介意)。
该调用使用exec
gawk 替换 shell,而不是将 gawk 作为子进程执行。 exit;
— 退出 shell,以防找不到 gawk。之后的任何内容都将被忽略,除非它应该是有效的 shell 语法,以防 shell 在开始执行之前尝试解析整行。
awk解析:
- 斜杠之间的位是正则表达式。
true + /REGEX/
- 一个条件。true
是一个未定义的变量,因此其数值为 0,但这并不重要。{}
— 如果上述条件成立,则不执行任何操作。
答案2
Gilles提出的解决方案确实是一个非常好的方法(终于有了在他的帖子中投票的声誉:))。
无论如何,据我了解该exec
命令,它使得exit
它后面的右边变得不必要,实际上无法访问,因为 shell 进程被替换为awk
.
此外,为了允许awk
脚本访问其调用参数,我建议对建议的解决方案进行一些更改:
#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here
允许-a "$0"
脚本访问它的调用名称,否则在访问变量时它总是会得到一个awk
or 。类似地,允许脚本访问数组中的其余参数,前面的它允许脚本接收参数而不用 gawk 解释它们就是为此目的。gawk
ARGV[0]
"$@"
ARGV[1...N]
--
-<something>
要记住/考虑的一件事是在脚本程序块的exit(0);
末尾添加一条语句,否则将威胁作为输入文件传递给脚本的所有参数。 (请注意,它与我们从行中删除的语句完全无关,这是一个无法访问的 shell 语句,而建议的退出位于 awk 代码中)。BEGIN { ... }
awk
awk
exit
true + ...
答案3
Shebang 本来就不那么灵活。可能有一些情况有第二个参数可以工作,我认为FreeBSD就是其中之一。
gawk 和操作系统附带的大多数实用程序预计将采用/usr/bin/
.
在较早的 UNIX 时代,通常/usr/
通过 NFS 或一些较便宜的介质进行安装,以节省本地磁盘空间和每个工作站的成本。/bin/
应该有启动所需的一切单用户模式。由于/usr/
没有安装在可靠的介质上,因此/bin/
包含足够的实用程序以使其足够友好,适合一般管理和故障排除。
这最初是在 Linux 中继承的,但由于磁盘空间不再是问题并且在大多数情况下/usr/
位于根文件系统中,当前的趋势是将所有内容都移入/usr/bin
(至少在 Linux 世界中)。因此,发行版安装的大多数实用程序都可以在那里找到。即使是最基本的实用程序,如cp
、rm
等ls
(好吧,还没有)。
关于 shebang 的选择。传统上,这是管理员或用户必须根据其环境进行编辑的内容。开发人员都知道,在其他人的系统中,解释器可能位于文件系统中的任何位置(例如/usr/local/bin
,/opt/gawk-4.0.1/bin
)。正确打包的脚本(rpm、deb 等)要么依赖于发行版包(即解释器具有已知位置),要么带有在安装期间设置正确 hashbang 的配置脚本。
答案4
如果安装了更现代的 coreutils (IIUC 8.30+),您现在可以使用
#!/usr/bin/env -S gawk -f
所有选项都将作为一个参数传递给 env,并且它将拆分它们