我有这样的通用代码。
#!/usr/bin/gawk -f
1 {
for (i=0;i<5;i++){
print $0
print $0, i > "/dev/stderr"
}
}
我想重定向到文件tmp,首先是stdout,然后是stderr。我尝试过gawk -f Documents/gawk_script.awk ./file &> tmp
。
但是此调用将附加到文件第一个stderr。我不想将它们分为两个文件,所以我想问是否有办法做到这一点。
./ file中有这样一行
hello
hello
howareyou
well
well
在tmp文件中
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
howareyou
howareyou
howareyou
howareyou
howareyou
well
well
well
well
well
well
well
well
well
well
well
hello 0
hello 1
hello 2
hello 3
hello 4
hello 0
hello 1
hello 2
hello 3
hello 4
howareyou 0
howareyou 1
howareyou 2
howareyou 3
howareyou 4
well 0
well 1
well 2
well 3
well 4
well 0
well 1
well 2
well 3
well 4
答案 0 :(得分:1)
我不确定您的意思,如果我理解的话...
如果要将stdout
重定向到file_out
,将stderr
重定向到file_err
,则可以执行此操作...
command > file_out 2> file_err
答案 1 :(得分:1)
There is no good way* to tell awk or the shell that it must buffer stderr until the tool finishes executing. Keep it simple and just do this:
awk -f script.awk file > out 2>tmp; cat tmp >> out && rm -f tmp
Otherwise you could buffer stderr yourself and print at the end (but this will only work for stderr messages you are manually printing, not messages gawk is generating itself):
{
for (i=0;i<5;i++){
print $0
errs = errs $0 OFS i ORS
}
}
END {
printf "%s", errs > "/dev/stderr"
}
and then call as:
awk -f script.awk file > out 2>&1
Of course you don't actually need to use stderr at all if that's all you're doing with it, just print to stdout.
*There may be some arcane incantation you can use to make this happen if the planets align a certain way and/or you have certain tools or a certain shell but just keep it simple as shown above.
答案 2 :(得分:1)
您遇到的问题是由于流stdout
和stderr
的缓冲。这两个流具有不同的默认缓冲区设置。尽管stdout
在写入终端时是行缓冲的,但在写入流/管道/文件时,缓冲得很好。另一方面,流stderr
是始终未被缓冲的。这就是为什么您首先在文件stderr
中遇到stdout
的输出,然后才遇到tmp
的输出的原因。但是请注意,当您输出更多行时,输出将被交错,因为突然stdout
的缓冲区将被填满并写入文件,然后再次输出stderr
,直到stdout
的下一个缓冲区已满。在下一页中很好地解释了该问题:
您可以应用的丑陋技巧之一是使用stdbuf
来更改awk
数据流的缓冲:
$ stdbuf -oL -eL awk '{...}' file.txt &> tmp.txt
在这里,我们使用stdbuf
将流stdout
和stderr
的缓冲模式设置为行缓冲,因此代码的输出将类似于:
hello
hello 1
hello
hello 2
...
如果您确实要先输出stdout
的所有 all ,然后才是stderr
的所有输出,则应遵循Ed Morton所述的方法。
答案 3 :(得分:0)
有点旧,但如果有人仍然需要它:
echo "some stuff" | awk '{
for (i=0;i<5;i++){
print $0;
# print i on stderr
system(">&2 echo " i);
}
}'