我目前正在编写一个awk脚本,如下所示:
#!/usr/bin/awk -f
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}我的脚本在我的电脑上运行得很好,但它不能移植……我想做一些像这样的事情
#!/usr/bin/env awk -f
...但是Debian shell不接受单个shebang中的多个参数。我得到了"awk -f" no such file or directory。有没有什么我可以使用的变通方法,或者这是完全不可能的?
发布于 2017-10-11 03:44:17
没有简单的方法可以干净利落地做到这一点;正如在glenn jackman's comment中提到的,shebangs是由execve()实现的,它只接受一个解释器和一个可选参数。
您需要一个变通方法。
这个问题的注释暗示您不需要包装器脚本,但是如果它包含在最终的~awk脚本中呢?
#!/bin/sh
awk -f - "$@" << 'EOF'
#!/usr/bin/awk -f
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}这在它的shebang中使用了可移植的POSIX shell,然后立即从标准输入(-f -)上的heredoc调用awk代码,将更多的参数和选项("$@")作为文件传递给awk。此处的文档是用引号(<< 'EOF')引用的,因此POSIX shell不会解释$0之类的内容。由于不存在仅由EOF组成的行,因此此处的文档以该文件结尾。
(第二个shebang不是由任何人读取的。对于阅读代码的人来说,它纯粹是装饰性的。如果使用.awk后缀命名此文件,vim等编辑器将默认将其语法突出显示设置为awk,而不考虑第一个shebang的内容。)
该代码不能将内容通过管道传输到文件中,因为脚本本身是通过管道传输到awk中的。如果你想支持管道,它需要更丑陋一点,使用bash的输入process substitution (<(…)):
#!/bin/bash
exec awk -f <(awk 'NR > 2' "$0") "$@"
#!/usr/bin/awk -f
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}这告诉bash在第二个awk命令创建的命名管道上执行awk,该命令读取完整的脚本(bash将$0解释为它正在运行的文件的名称),并打印第3行和更高的行。同样,第二个shebang纯粹是表面上的,因此只是一个评论。
发布于 2017-10-11 04:07:23
真的没有理由在shebang中调用awk。只需通过sh调用它:
#!/bin/sh
exec awk '
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}
' "$@"https://stackoverflow.com/questions/45612626
复制相似问题