Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 将printf重定向到awk中的文件_Linux_Bash_Awk - Fatal编程技术网

Linux 将printf重定向到awk中的文件

Linux 将printf重定向到awk中的文件,linux,bash,awk,Linux,Bash,Awk,我有一个简单的bash脚本 其目的是监视http访问日志文件(test.log)并将更新的命中率输出到文件(out.log): stdbuf -o0 tail -f test.log | awk -F'[ "]+' '{ ipcount[$1]++; print "test" > "out.log"; #Truncate out.log for (i in ipcount) { printf "%15s - %d\n", i, ipcount[i] >

我有一个简单的bash脚本

其目的是监视http访问日志文件(test.log)并将更新的命中率输出到文件(out.log):

  stdbuf -o0 tail -f test.log | awk -F'[ "]+' '{
  ipcount[$1]++;
  print "test" > "out.log"; #Truncate out.log
  for (i in ipcount) {
        printf "%15s - %d\n", i, ipcount[i] >> "out.log";
        printf "%15s - %d\n", i, ipcount[i] }
}'
主要逻辑是有效的。我唯一的问题是重定向到“out.log”似乎不起作用。 最后一个printf将预期结果输出到标准输出。 但是另外两个printf没有向“out.log”输出任何内容,我也不明白为什么。
out.log拥有所有权限(777)

这应该适用于您:

tail -f test.log | awk -F'[ "]+' -v out_file="out.log" '{
    val_count[$1]++
    print "" > out_file

    for (i in val_count) {
        printf "%15s - %d\n", i, val_count[i] >> out_file
        printf "%15s - %d\n", i, val_count[i]
    }

    close(out_file)
}'
(注意:我将输出文件定义移动到命令行以减少重复。)

您的原始版本有一个致命问题:
print”“>“out.log”
只截断
out.log
调用它的第一次时间。对它的所有后续调用都将简单地附加到它,因为它已经打开。作为第二个问题,awk喜欢缓冲输出,因此内容只会间歇性地刷新

为了解决这个问题,我们需要在每次迭代后关闭文件。这将强制将输出刷新到
out.log
,并强制
重定向在下一次迭代时重新截断文件。如果您不需要截断每个迭代,一个简单的
fflush(out\u文件)
就足够了


为了更清楚地说明这个问题

这会导致一个
output.txt
,它有多行,因为它只被截断一次(第一次迭代):

这将导致一个
output.txt
,其中有一个输出行,因为它被截断多次:

ls -l | awk '{ print "This file has one line" > "output.txt"; close("output.txt"); }'

如果您删除输出文件周围的引号,例如仅
printf“text”>>output.log
?这是
awk
问题,而不是
bash
问题。是否有理由不将awk的所有输出重定向到一个文件?@unixarmy-尝试不使用引号时,我在“.”(点)上得到语法错误这将文件名和扩展名分开。@Soren,请注意,在循环之前,我要截断文件,并在循环中附加到。啊哈!谢谢你的解答和解释。这个解决方案对我有效。尽管在我的环境中,初始代码在out.log中没有输出,这与您在环境中的体验不同。无论如何,下次我不会忘记关闭文件句柄;)@Yan4321-啊,另一个障碍是awk喜欢缓冲输出(除非输出是到终端的)。要解决这个问题,您需要
fflush
文件或流。
ls -l | awk '{ print "This file has one line" > "output.txt"; close("output.txt"); }'