Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to figure out how I can use AWK to subtract lines. For example, imagine the input file is:

30
20

The output would be:

10

Now, as a test I am trying to calculate the "Used" memory column from:

$ cat /proc/meminfo

So at the moment I have written this:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    -- Here comes the calculation using AWK

I have tried the following:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk '{$0-s}{s=$0} END {print s}' 

But this just gives me the last row of data.

I've found a working solution, but I doubt it's the most optimal one. All my coding experience tells me that hard coding the amount of rows is terrible :P

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk 'NR == 1{s=$0} NR == 2 {s=s-$0} END {print s}'
share|improve this question
    
What would you want done with N rows? Should the final result be line1_$2 - line2_$2 - lineN-$2? Do you only want to subtract the first two consecutive rows? –  terdon Mar 2 at 16:55

3 Answers 3

up vote 8 down vote accepted

You can also do this using awk, paste, and bc. I find this approach easier to remember, the syntax of awk always requires me to look things up to confirm.

NOTE: This approach has the advantage of being able to contend with multiple lines of output, subtracting the 2nd, 3rd, 4th, etc. numbers from the 1st.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | paste -sd- - | bc
7513404

Details

The above uses awk to select the column that contains the numbers we want to subtract.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'
7969084
408432

We then use paste to combine these 2 values values and add the minus sign in between them.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- -
7969084-346660

When we pass this to bc it performs the calculation.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404
share|improve this answer
    
@terdon - thanks I was making that edit when you did it 8-) –  slm Mar 2 at 17:00

The purely awk solution, no redundant cat or grep commands:

awk '/MemTotal/ {TOT=$2} /MemFree/ {FREE=$2} END {printf("%d kB Used\n", TOT-FREE)}' /proc/meminfo

I see awk_FTW beat me to it but I though formatting the output could be nice.

share|improve this answer

Try this:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
share|improve this answer

Your Answer

 
discard

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.