Page 1 of 3

How to get specific results from 'free -m' ?

Posted: Thu 16 Aug 2018, 03:58
by ITSMERSH
Hi.

I need to get some specific results from 'free -m' into a variable.
Output 'free -m' wrote: total used free shared buffers
Mem: 3987 1490 2497 0 3
-/+ buffers: 1486 2501
Swap: 9039 99 8940
I need those values marked bold - which is total memory / free memory.

Is there a simple and/or easy way to achieve?

Thanks

Edit:

After a some time of try and fail I could achieve it that way:
FREERESULT="`free -m`"
TOTAL=$(echo $FREERESULT|cut -d':' -f2|cut -d' ' -f2)
FREE=$(echo $FREERESULT|cut -d':' -f2|cut -d' ' -f4)
Since there's two more lines including ':', is this secure?

Is there something smarter, a one liner probably?

Re: How to get specific results from 'free -m' ?

Posted: Thu 16 Aug 2018, 05:10
by MochiMoppel
ITSMERSH wrote:Is there something smarter, a one liner probably?
Isn't your solution smart enough? Sure you could assign 2 variables in one line, but the result would look ugly.

Another way:

Code: Select all

FREERESULT=(`free -m`)
TOTAL=${FREERESULT[6]}
FREE=${FREERESULT[8]}

Posted: Thu 16 Aug 2018, 05:17
by 01micko
You can make a one-liner with read (and grep). Note that using read like this is a bashism.

Code: Select all

# read a b c d e f g <<<$(free -m|grep '^Mem')
# echo $b $d

Posted: Thu 16 Aug 2018, 05:33
by MochiMoppel
grepless:

Code: Select all

read x x x x x x TOTAL x FREE x <<< $(free -m)

Posted: Thu 16 Aug 2018, 05:40
by fredx181
MochiMoppel wrote:Another way:
Code:
FREERESULT=(`free -m`)
TOTAL=${FREERESULT[6]}
FREE=${FREERESULT[8]}
That doesn't work with newer version

Code: Select all

# free --version
free from procps-ng 3.3.12
Output is different from older:

Code: Select all

# free -m
              total        used        free      shared  buff/cache   available
Mem:           2011         301         852         114         857        1376
Swap:          3184           0        3184
Fred

Posted: Thu 16 Aug 2018, 05:41
by musher0
Hello *RSH.

Code: Select all

free -m | awk '$1 ~ /Mem/ { print $2,$4 }'
This way you get only the desired results.
You can change the , to "\t" if you wish the line to "breathe" more.

Examples:

Code: Select all

free -m | awk '$1 ~ /Mem/ { print $2,$4 }'
3914 2630

free -m | awk '$1 ~ /Mem/ { print $2"\t"$4 }'
3914	2593
Awk is totally secure, BTW. Unused data is discarded to /dev/null, as I
understand it.

IHTH

Posted: Thu 16 Aug 2018, 05:47
by MochiMoppel
fredx181 wrote:That doesn't work with newer version

Code: Select all

# free --version
free from procps-ng 3.3.12
In my puppy free is linked to busybox

This should work in any version:

Code: Select all

FREERESULT=(`free -m|grep Mem:`)
TOTAL=${FREERESULT[1]}
FREE=${FREERESULT[3]}
.

Posted: Thu 16 Aug 2018, 05:56
by musher0
To make it a bit more informative:

Code: Select all

echo -e "total\tfree";free -m | awk '$1 ~ /Mem/ { print $2"\t"$4 }'
total	free
3914	2568

Posted: Thu 16 Aug 2018, 06:02
by fredx181
MochiMoppel wrote:In my puppy free is linked to busybox
Ah, yes, probably the case in all puppies, so my post above can be ignored.

Posted: Thu 16 Aug 2018, 06:17
by MochiMoppel
fredx181 wrote:Ah, yes, probably the case in all puppies, so my post above can be ignored.
So probably my edit can be ignored too :lol:

Posted: Thu 16 Aug 2018, 06:18
by musher0
Hi *RSH.

Careful, it's a memory clean-up script! It's not exactly what you are looking
for, but there may be some code you wish to plunder ;) in here:
http://murga-linux.com/puppy/viewtopic. ... ost#831720

It's derived from Joe Arose's original, way back when, with add-ons /
suggestions from various forum members. It may save you some time,
who knows.

IHTH.

Posted: Thu 16 Aug 2018, 07:21
by ITSMERSH
Wow, thanks for all the replies! :)

A lot to check out...

Posted: Thu 16 Aug 2018, 14:53
by rockedge
MochiMoppel I took your code snip and using it as an icon on the desktop

Code: Select all

#!/bin/sh
FREERESULT=(`free -h|grep Mem:`)
TOTAL=${FREERESULT[1]}
FREE=${FREERESULT[3]}
gxmessage "Total->$TOTAL  Free->$FREE"

Posted: Thu 16 Aug 2018, 19:25
by musher0
@*RSH: You're welcome!

Understanding AWK (awk)

Posted: Tue 06 Nov 2018, 21:03
by ITSMERSH
musher0 wrote:

Code: Select all

free -m | awk '$1 ~ /Mem/ { print $2,$4 }'
Today I was in the need to get specific results from --> uptime <-- to show some statistics in a gui. The output of --> uptime <-- varies dependent on how long the computer is running.

So I wrote a small line to get the desired information.

Code: Select all

UPTIME="`uptime | cut -d ' ' -f 4 | cut -d ',' -f 1` hours"
But after the computer was running for more than 24 hours this line returned just --> 1 <-- instead of e.g. 25:43.

So I was in the need to modify the above line of code.

Thanks to the coded line above by musher0 it seems I'm going to understand --> awk <-- at least a little. So, here's how I extracted that desired information when the computer is running for more than 24 hours.

Code: Select all

# Get up-time of running System
UPTIME="`uptime`"; echo "$UPTIME" > /tmp/upt;
if (grep 'day' /tmp/upt >/dev/null) then
	UPTIME1=`uptime | awk '$2 ~ /up/ { print $3,$4,$5 }' | cut -d ',' -f 1`
	UPTIME2=`uptime | awk '$2 ~ /up/ { print $3,$4,$5 }' | cut -d ',' -f 2`
	UPTIME="$UPTIME1, $UPTIME2 hours"
	else
	UPTIME="`uptime | cut -d ' ' -f 4 | cut -d ',' -f 1` hours"
fi
Of course, I'm sure there's some smarter solution by the experts here. Though, I'm somehow glad to have understood a bit more of those special functions.

Thank you, musher0 ! :D

Posted: Tue 06 Nov 2018, 22:32
by musher0
Hello Rainer.

My pleasure!

But maybe you would prefer this format:

Code: Select all

uptime | awk '{ print $3,$4,$5}' | awk -F"," '{ print $1","$2}'
It will output something like:
5 days, 19:56
Or this:

Code: Select all

Minutes="`uptime | awk -F"," '{ print $2 }' | awk -F":" '{ print $2 }'`";Hours="`uptime | awk '{ print ($3*24)+$5}'`";echo "Uptime: $Hours h $Minutes m"
It will output something like:
Uptime: 140 h 32 m
Depending on your needs of course.

I mention it because "awk purists" try not to use awk and cut on the same
line. We simply repeat an awk command to fish out the desired data.

And as you say, I am far from being an awk expert, although I have some
experience with it. I am sure someone can come up with better awk code
for your need.

Have fun!

Posted: Wed 07 Nov 2018, 01:23
by ITSMERSH
rockedge wrote:MochiMoppel I took your code snip and using it as an icon on the desktop
#!/bin/sh
FREERESULT=(`free -h|grep Mem:`)
TOTAL=${FREERESULT[1]}
FREE=${FREERESULT[3]}
gxmessage "Total->$TOTAL Free->$FREE"
I needed to change the -h to -m to get this to work from script.

Thanks @musher0.

I'm sure I will play a little with all of that next...

Posted: Wed 07 Nov 2018, 02:59
by MochiMoppel
You should be aware that (most?) Puppies use the busybox version of uptime.

On 2 of my machines uptime produced these outputs:
  • 11:12:04 up 17 min, load average: 0.00, 0.02, 0.04
    11:13:56 up 29 days, 43 min, load average: 0.16, 0.26, 0.27
None of the proposed awk solutions would work.

Posted: Wed 07 Nov 2018, 03:19
by ITSMERSH
Here is mine:

04:16:02 up 2 days, 58 min, load average: 0.35, 0.41, 0.47

It seems I need to do a 3rd modification in case there's only minutes and no hours. :roll:

Re: Understanding AWK (awk)

Posted: Wed 07 Nov 2018, 08:38
by MochiMoppel
ITSMERSH wrote:So I wrote a small line to get the desired information.

Code: Select all

UPTIME="`uptime | cut -d ' ' -f 4 | cut -d ',' -f 1` hours"
ITSMERSH also wrote:Here is mine:
04:16:02 up 2 days, 58 min, load average: 0.35, 0.41, 0.47
If this is yours, your small line produces days hours

My computer is now running for more than an hour and less than a day, my uptime produces
17:24:36 up 5:17, load average: 0.00, 0.03, 0.05
and your code returns load hours

I wonder if using the uptime command is the right approach. You may want to consider to read the /proc/uptime value directly.