5

I want to use the AWK redirection feature and what I've done so far is this :

$ vmstat 1 | awk ' { print $2 > "outfile" } '

*Actually the commands before awk are a lot more complicated , but it's a simplified demonstration.

If I run the above command without redirection , I would get the desired result in the stdout. But after redirecting it to outfile , it's still empty :

$ cat outfile
$

What's wrong with that ?

TIA.

4
  • Does giving awk the -W interactive option help? Commented Jun 6, 2020 at 23:39
  • @MarkPlotnick "awk: option `-W interactive' unrecognized, ignored" . I used it as follows : "vmstat 1 | awk -W interactive ' { print $1 } ' " . Btw I use awk 4.1.4. Commented Jun 7, 2020 at 0:04
  • 1
    OK. There are a few different implementations of awk out there, and -W interactive is supported by mawk. Commented Jun 7, 2020 at 11:26
  • @MarkPlotnick Mine is Gawk . But I have Mawk too . Thank you anyway. Commented Jun 7, 2020 at 14:12

2 Answers 2

6

awk buffers its output. If your awk implementation provides it (as gawk, mawk1, nawk, and BSD awk do), use fflush().

  fflush([file])        Flush any buffers associated with the open output file 
                        or pipe file.  If file is missing or if it is  the null 
                        string,  then  flush  all open output files and pipes.

So, write it this way:

vmstat 1 | awk '{print $2 > "outfile"; fflush()}'

The GNU awk manual I/O section on fflush is a worth reading. There you will also find that fflush has been accepted to the next POSIX standard.


As an extra, notice that you can give the number of samples that vmstat should output. So, if you want only 5 samples (for example), you can wait the 5 seconds until the command terminates and then the file will contain the output:

vmstat 1 5 | awk '{print $2 > "outfile"}'

1With mawk the syntax is a bit different: mawk -W interactive '{print $2 > "outfile"; fflush("")}'.

5
  • 1
    There appears to be a slight difference in usage between gawk, which says of fflush([file]) If file is missing or if it is the null string, then flush all open output files and pipes. and mawk which says fflush without an argument flushes stdout. fflush with an empty argument ("") flushes all open output.. Regardless, I can't seem to get the above to work with mawk v.1.3.3 nor v.1.3.4 , either with fflush() or fflush(""). Any idea why? Commented Jun 6, 2020 at 23:01
  • 1
    @steeldriver Thanks for catching that. I reproduced that behavior but no, I do not know what is going on there with mawk. I updated the answer to include that. I will contact Thomas Dickey to see if he could dispel our confusion. Commented Jun 6, 2020 at 23:55
  • 1
    For mawk, add the -W interactive option. Commented Jun 9, 2020 at 8:19
  • @steeldriver mawk also has that peculiar behaviour in that it waits until it has accumulated a buffer-full of input before considering processing it, disabled with -W interactive. Commented Jun 9, 2020 at 11:44
  • @StéphaneChazelas thanks - that was indeed what I was missing Commented Jun 9, 2020 at 22:42
6

The problem is buffering, it can be disabled.

vmstat 1 | stdbuf -o0 awk '{print $2}' >> out
  • -o output stream
  • 0 stream will be unbuffered

or you can call vmstat in while loop with sleep 1

while true; do 
     vmstat | awk '{print $2}' >> output.file
     sleep 1
done
2
  • 1
    You should also be able to place the piping to awk after the loop: ... done | awk ... >out. Commented Jun 6, 2020 at 23:55
  • Thanks. For me this was the solution to my command not working command "ping mymachine | stdbuf -o0 awk -F= '{print $4}' > ping.dat" Commented Oct 17, 2024 at 9:39

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.