Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For example,

If you do free -m | sed -n 2p

I want to work with the output from the last, second to last, and third columns. The problem is I want to keep it consistent and use the output from free once.

I want to be able to keep the output consistent without running the free -m | sed -n 2p and extracting what the three columns that I need three times; I want to be able to do it once. How can I do this?

share|improve this question
Just to make sure I'm understanding this correct: You want to generate a dataset, and then generate three new independent datasets based on the original dataset, but without regenerating the original dataset each time? I don't think this can be done simply with piping, but it might be possible with subshelling or temporary files. – Darth Android Jul 18 '12 at 15:59
up vote 3 down vote accepted

You might want to give Awk a whirl for this.

[root@james-ws tmp]# free -m | sed -n 2p
Mem:          3948       3724        223          0        364        852
[root@james-ws tmp]# free -m | sed -n 2p | awk '{print $7, $6, $3}'
852 364 3718
share|improve this answer

You can use named pipes and awk to split the output into 3 sources. Then you can read (once) from each source.

mkfifo pipe1 pipe2 pipe3
free -m | sed -n 2p | awk '{ print $3 >> pipe1; print $6 >> pipe2; print $7 >> pipe3 }'

The named pipes pipe1 et al. act as buffers that you can read from as if they were pipelines.

cat pipe1 | this | that | the-other

or preferably without cat:

this < pipe1 | that | the-other

Note that once you read data from a pipe, the data is gone, just as if your input came from a regular pipe.

share|improve this answer

I think the simplest way to do this would be to store the statistics line in a bash array, and then access the elements of the array:

memStats=( $(free -m | sed -n 2p) )
echo "last column: ${memStats[memStatElements-1]}"
echo "second-to-last column: ${memStats[memStatElements-2]}"
echo "second column: ${memStats[1]}" # Note that arrays are 0-based, so [1] is the second element
share|improve this answer

I opted to instead just store the free result in a variable and echo each result individually.

This is my end result:

STRINGMEM=$(free -m | sed -n 2p | awk '{ print $7,$6,$3 }'); CACHED=$( echo $STRINGMEM | awk '{print $3}'); BUFFERED=$(echo $STRINGMEM | awk '{print $2}'); ACTIVE=$(echo $STRINGMEM | awk '{print $1}'); ACTIVE=$( (( ($BUFFERED + $CACHED) - $ACTIVE)) ); DATE=$(date +%s);
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.