Extracting information using awk

I want to write a script that extracts a value from a line of text. I know it can be done using awk but I've never used awk before so I don't know how to do it. The text is:

Mem: 100M Active, 2150K Cache, 500M Buf, 10G Free

I want to extract the free memory value to use as a variable. In this example what I want is 10G.

My initial guess is that it is something about extracting the 8th field using awk. Does this need to be converted from ASCII to be interpreted as a number (10,000,000,000)?

The value of 'free' is worthless without knowing the value of 'cache' too, since cache counts as free memory. If you've been rebooting every time free goes low, you don't need to.

$ echo Mem: 100M Active, 2150K Cache, 500M Buf, 10G Free | awk '{print $8}'
10G

$ echo Mem: 100M Active, 2150K Cache, 500M Buf, 10G Free | awk '{print substr($8,length($8),1)}'
G

The first line shows how to extract.
The 2nd line pulls the 'G' out. You will need to analyze for all the possibilities - K, M, G, ??? to convert and create a number.

1 Like

Thanks. That worked a charm :slight_smile:

How do I remove the G from the 10G i.e. only display the 10?

$ echo Mem: 100M Active, 2150K Cache, 500M Buf, 10G Free | awk '{print substr($8,1,length($8)-1)}'
10

1 Like

If you want the value converted to a number, you can try something like:

awk '
BEGIN { factor=1000     # change 1000 to 1024 if using ISO/IEC values
}
function f(v,   ind) {
        ind = index("KMGTPE", substr(v, length(v), 1))
        return(substr(v, 1, length(v) - 1) * (factor ^ ind))
}
{       printf("%s\n", $8 ~ /^[0-9]*[KMGTPE]$/ ? f($8) : $8)
}' input.txt

As always, if you're using a Solaris/SunOS system, use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of awk .

I left off the multipliers for zettabyte (Z) and yottabyte (Y) because the floating point types usually used by awk implementations don't have enough precision to compute the correct value in those ranges. If a multiplier given in the input is not known, it is printed unchanged. With the input file:

Mem: 100M Active, 2150K Cache, 500M Buf, 990 Free
Mem: 100M Active, 2150K Cache, 500M Buf, 991K Free
Mem: 100M Active, 2150K Cache, 500M Buf, 992M Free
Mem: 100M Active, 2150K Cache, 500M Buf, 993G Free
Mem: 100M Active, 2150K Cache, 500M Buf, 994T Free
Mem: 100M Active, 2150K Cache, 500M Buf, 995P Free
Mem: 100M Active, 2150K Cache, 500M Buf, 996E Free
Mem: 100M Active, 2150K Cache, 500M Buf, 997Z Free
Mem: 100M Active, 2150K Cache, 500M Buf, 998Y Free
Mem: 100M Active, 2150K Cache, 500M Buf, 999u Free

the above script produces the following output:

990
991000
992000000
993000000000
994000000000000
995000000000000000
996000000000000000000
997Z
998Y
999u
1 Like