5

awk 脚本似乎将ARGV[1]ARGV[ARGC]视为输入文件。

有没有办法让 awk 考虑ARGV作为简单的参数而不是输入文件

例子:

测试.awk

#!/usr/bin/awk -f
BEGIN {title=ARGV[2]}
{if ($1=="AA") {print title}}

数据文件

AB
BA
AA
CC

$ test.awk dat 'My Interesting Title'

我的有趣标题 awk:test.awk:3:致命:无法打开文件“我的有趣标题”进行阅读(没有这样的文件或目录)

4

5 回答 5

8

您可以随时修改ARGV。awk 会依次处理 的元素ARGV,因此如果在处理过程中修改它们,可以安排读取不同的文件或不将某些参数视为文件名。特别是,如果您ARGVBEGIN块中进行修改,则一切皆有可能。例如,以下代码片段导致 awk 即使在传递参数时也从标准输入读取,并将参数保存在名为 的数组中args

awk '
    BEGIN {for (i in ARGV) {args[i] = ARGV[i]; delete ARGV[i]}}
    …
' hello world

如果您只想跳过第一个参数,只需删除它:

awk '
    BEGIN {title = ARGV[1]; delete ARGV[1]}
    $1 == "AA" {print title}
' 'My Interesting Title' input.txt

然而,这是不寻常的,因此可能被认为难以维护。考虑使用 shell 包装器并改为通过环境变量传递标题。

#!/bin/sh
title=$1; shift
awk '
    $1 == "AA" {print ENV["title"]}
' "$@"

您还可以将字符串作为 awk 变量传递。请注意,该值会经历反斜杠扩展。

awk -v 'title=My Interesting Title\nThis is a subtitle' '
    $1 == "AA" {print title}  # prints two lines!
' input.txt
于 2013-09-16T10:07:54.547 回答
3

像这样的东西?

$ awk -v title='My Interesting Title' '$0 ~ /AA/ {print title}1' input
AB
BA
My Interesting Title
AA
CC
于 2013-09-16T09:54:27.197 回答
1

是的:

BEGIN{title=ARGV[2];ARGV[--ARGC]=""}
$1=="AA" {print title}

但你可能想要这个:

$ cat tst.sh
awk -v title="$2" '$1=="AA" {print title}'

请参阅http://cfajohnson.com/shell/cus-faq-2.html#Q24以了解有关将 shell 变量的值传递给 awk 脚本的这些方法和其他方法的详细信息。

顺便说一句,请注意,无论您使用此脚本还是您的原始脚本,文件的内容都是调用 awk 的 shell 脚本,而不是 awk 脚本,因此后缀不应该是.awk,应该是.sh或类似的。

于 2013-09-16T13:07:32.983 回答
1
于 2014-09-13T09:17:41.050 回答
0

allow also

awk 'BEGIN {title=ARGV[2]}
           {if ($1=="AA") {print title}}
    ' input.txt -v "title=My Interesting Title"

argument for ARGV are also any string (argument of command line) of format varname=VarContent

于 2015-06-08T11:57:36.050 回答