将参数传递给awk脚本文件

49

如果我想向awk脚本文件传递参数,我该怎么做?

#!/usr/bin/awk -f

{print $1}

我想在脚本中打印从shell传递给脚本的第一个参数,例如:

bash-prompt> echo "test" | ./myawkscript.awk hello
bash-prompt> hello

3
完整的 Awk 教程可用 - suneet saini
3个回答

65
在awk中,$1引用的是记录中的第一个字段,而不像在bash中一样引用第一个参数。你需要使用ARGV来代替。请查看这里以了解官方文档:here
脚本:
#!/bin/awk -f

BEGIN{
    print "AWK Script"
    print ARGV[1]
}

示例:

$ ./script.awk "Passed in using ARGV"
AWK Script
Passed in using ARGV

1
注意:在 BSD 和 macOS 中包含的 awk 版本中,ARGC 和 ARGV 内置变量不可用。它们在 GNU awk (gawk) 中可用。 - AliA
@AliA 这是错误的。我使用的是 macOS 13.2(我相信它有 BSD 版本的 awk),它已经被文档化了。它也是 POSIX 的一部分。 - tmillr
@tmillr 你是对的。它在 macOS 12.6.1 中也可用。 - AliA

48

你可以在命令行使用-v作为一个选项,来向脚本提供一个变量:

假设我们有一个名为script.awk的文件内容如下:

BEGIN {print "I got the var:", my_var}

然后我们像这样运行它:

$ awk -v my_var="hello this is me" -f script.awk
I got the var: hello this is me

4
在我看来,这是唯一真正回答了问题的答案。此外,如果您的脚本是可执行的,您可以执行以下操作:cat file | script.awk -v my_var="hello this is you" - xdhmoore

24

你的hash bang定义了这个脚本不是shell脚本,而是一个awk脚本。你不能在脚本中以bash方式执行它。

另外,你所做的:echo blah|awk ... 并没有传递参数,而是将echo命令的输出通过管道传递给另一个命令。

你可以尝试以下这些方法:

 echo "hello"|./foo.awk file -
或者
var="hello"
awk -v a="$var" -f foo.awk file

通过这样,你的foo.awk中有变量a,你可以使用它。

如果你想要做一些像shell脚本接受$1 $2这样的变量,你可以写一个小的shell脚本来包装你的awk代码。

编辑

不,我没有误解你。

我们来看一个例子:

假设你的x.awk文件包含以下内容:

{print $1}

如果你这样做:

echo "foo" | x.awk file

它与以下内容相同:

echo "foo"| awk '{print $1}' file

这里 awk 的输入只有 file,你的 echo foo 没有意义。如果你这样做:

  echo "foo"|awk '{print $1}' file -
or
    echo "foo"|awk '{print $1}' - file

awk需要两个输入(用于awk的参数),一个是标准输入,另一个是文件,在您的awk脚本中,您可以:

awk需要两个输入(用于awk的参数),一个是标准输入,另一个是文件,在您的awk脚本中,您可以:

echo "foo"|awk 'NR==FNR{print $1;next}{print $1}' - file

这将打印你的回声中第一个 foo,然后是file的column1。当然,这个例子实际上不执行任何操作,只是将它们全部打印出来。

你可以有多于两个输入,而且不需要检查NR和FNR,你可以使用

ARGC   The number of elements in the ARGV array.

ARGV   An array of command line arguments, excluding options and the program argument, numbered from zero to ARGC-1

例如:

echo "foo"|./x.awk file1 - file2

那么你的“foo”是第二个参数,你可以通过 ARGV[2] 在你的 x.awk 中获取它。

echo "foo" |x.awk file1 file2 file2 -

现在是ARGV[4]的情况。

我的意思是,你的echo "foo"|..会成为awk的stdin,它可以是awk的第一个或第N个"参数"/输入,具体取决于你在哪里放置了-(stdin)。你必须在你的awk脚本中处理它。


1
你有误解,你理解成 echo blah | awk ... 的意思是我在向 awk 脚本传递参数。 请再读一遍。 - Mahmoud Emam
1
很好的点赞评论 :).. @UNIX 看到编辑了,希望现在清楚了。 - Kent
很快就会有UNIX,如果你想让你的 echo foo|./x.awk file 先打印出 foo,那么请使用 echo foo|./x.awk - file - Kent
回到这个答案(我收藏了这个问题来做到这一点)。我不能像 awk {print 1} 这样做。这是否意味着 awk 总是需要 awk <commands> filesomething | awk <commands> - fedorqui
@fedorqui,你可以不需要输入就做到这一点。awk 'BEGIN{print "kent"}' - Kent
啊,我明白了。它必须在“BEGIN”块内部,否则它会期望一些标准输入。这让我的一天变得美好(有点口胡 :D)。谢谢,@Kent! - fedorqui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接