我目前正在编写一个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
。我可以使用任何解决方法,还是完全不可能?
答案 0 :(得分:0)
没有简单的方法可以干净利落地做到这一点;如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,并传递其他参数和选项("$@"
) awk as files。引用了heredoc(<< 'EOF'
),因此$0
之类的东西不会被POSIX shell解释。由于不存在仅由EOF
组成的行,因此heredoc以文件结束。
(第二个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纯粹是装饰性的,因此只是一个评论。
答案 1 :(得分:0)
没有理由在shebang中调用awk。只需通过sh:
调用它#!/bin/sh
exec awk '
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}
' "$@"