There is no easy way to do this cleanly; as mentioned in glenn jackman's comment, shebangs are implemented by execve(), which only accepts an interpreter and a single optional argument.
You'll need a workaround.
The comments to the question imply you don't want a wrapper script, but what if it's contained inside the final ~awk script?
#!/bin/sh
awk -f - "$@" << 'EOF'
#!/usr/bin/awk -f
BEGIN {
print "Starting extracting data"
}
{
print $0
}
END {
print "End of file"
}
This uses portable POSIX shell in its shebang and then immediately invokes awk with awk code from a heredoc on standard input (-f -), passing the further arguments and options ("$@") to awk as files. The heredoc is quoted (<< 'EOF') so things like $0 aren't interpreted by the POSIX shell. Since a line consisting solely of EOF is not present, the heredoc ends with the file.
(The second shebang is not read by anything. It's purely cosmetic for people who read the code. If you name this file with the .awk suffix, editors like vim will default their syntax highlighting to awk despite the contents of the first shebang.)
That code won't work for piping content into the file because the script is itself piped into awk. If you want to support piping, it needs to be a little uglier, using bash's input 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"
}
This tells bash to execute awk on a named pipe created from that second awk command, which reads the full script (bash interprets $0 as the name of the file it is running) and prints lines 3 and higher. Again, the second shebang is purely cosmetic and is therefore just a comment.
awk?#!/usr/bin/env awkand pass-fwhile calling the script.execve(2)man page