我有一个 awk 脚本,如下所示:
#!/bin/awk -f
BEGIN{}
{
for(i=1;i<=NF;i++)
sum+=$i; #sum of 3 numbers in a row
printf "Hello %d%s, %s %s, %d\n",NR,OFS, $1,$2,j;j=0
print > "hellofile1"
}
END{}
我希望 .awk 文件在 hellofile1 中具有以下输出
1st field 2nd field
Hello 1 ... ...
Hello 2 ... ...
Hello 3 ... ...
但是当我按如下方式运行它时:awk -f hf.awk hello 它会出现 '>' 和 '>>' 的错误。PS print 命令外面的 $1 指的是 hello 文件作为参数。
答案1
您无法重定向块的输出awk
(这指的是问题的早期版本)。您还需要双引号输出文件的名称(这也指问题的早期版本)。空的BEGIN
和END
块可以完全移除。
相反,如果您只想为文件的所有行添加前缀Hello N
,则N
与当前行号对应的整数在哪里(这正是我能够推断出您想要做的,并且代码已在在撰写此答案期间至少一次;您显然可以修改它以执行您实际需要执行的操作),使用
{
printf "Hello %d%s%s\n", NR, OFS, $0 >"hellofile1"
# or: print "Hello " NR, $0 >"hellofile1"
}
这会将输入文件的每一行打印到文件中hellofile1
,并以字符串Hello
、行号和输出字段分隔符(默认为空格)为前缀。
输出文件hellofile1
将由于 而被截断>
,但awk
保持文件打开以进行写入,直到显式关闭它(此处不会发生),或直到程序结束,因此程序的所有输出都将正确打印到文件中(后续print >
调用将附加到已打开的文件中)。
另一种方法可以做到这一点:
{
for (i = NF; i >= 1; --i)
$(i+1) = $i
$1 = sprintf("Hello %d", NR) # or: $1 = "Hello " NR
print >"hellofile1"
}
这会将现有字段“向右”移动一个字段,并将字符串Hello N
作为记录中的第一个字段插入。然后它将记录打印到输出文件。请注意,这会重新形成记录并OFS
在输出中用(默认情况下为空格)分隔它们的字段。
你可以用它作为
$ awk -f script.awk myfile
其中有myfile
一些您想要用作输入的文件。
答案2
$1
在块内使用或任何其他字段是没有意义的BEGIN{}
,它BEGIN
是在读取文件之前执行的,因此没有定义字段。:
$ echo foo | awk 'BEGIN{print "The first field is:", $1}'
The first field is:
而且空块也是没有意义的END{}
。也就是说,我想你想要的只是这样:
awk '{print "Hello",NR,$0 > "outFile"}' inFile
或者,另一种选择:
awk '{print "Hello",NR,$0}' inFile > outFile
如果您在这样的文件上运行上面的命令:
$ cat file
field1 field2
field1 field2
field1 field2
field1 field2
field1 field2
你会得到:
$ awk '{print "Hello",NR,$0 > "outFile"}' file
$ cat outFile
Hello 1 field1 field2
Hello 2 field1 field2
Hello 3 field1 field2
Hello 4 field1 field2
Hello 5 field1 field2
在 awk 脚本中,这将是:
#!/bin/awk -f
{
print "Hello",NR,$0 > "outFile"
}
答案3
1 美元,>和>>是来自 bash 的概念,但脚本的解释器是 /bin/awk (根据脚本的第一行)。恕我直言,您可以尝试从 bash 脚本内部调用 awk 脚本,或者尝试使用 HEREDOC 将所有内容放在同一个文件中。
更新:bash/awk 这里文档示例这里