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

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
ITSMERSH

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

#1 Post 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?

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

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

#2 Post 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]}

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#3 Post 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
Puppy Linux Blog - contact me for access

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#4 Post by MochiMoppel »

grepless:

Code: Select all

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

User avatar
fredx181
Posts: 4448
Joined: Wed 11 Dec 2013, 12:37
Location: holland

#5 Post 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

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#6 Post 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
Last edited by musher0 on Thu 16 Aug 2018, 05:52, edited 1 time in total.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#7 Post 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]}
.
Last edited by MochiMoppel on Thu 16 Aug 2018, 06:13, edited 1 time in total.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#8 Post 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
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
fredx181
Posts: 4448
Joined: Wed 11 Dec 2013, 12:37
Location: holland

#9 Post 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.

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#10 Post 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:

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#11 Post 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.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

ITSMERSH

#12 Post by ITSMERSH »

Wow, thanks for all the replies! :)

A lot to check out...

User avatar
rockedge
Posts: 1864
Joined: Wed 11 Apr 2012, 13:32
Location: Connecticut, United States
Contact:

#13 Post 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"

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#14 Post by musher0 »

@*RSH: You're welcome!
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

ITSMERSH

Understanding AWK (awk)

#15 Post 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

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#16 Post 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!
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

ITSMERSH

#17 Post 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...

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#18 Post 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.

ITSMERSH

#19 Post 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:

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

Re: Understanding AWK (awk)

#20 Post 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.

Post Reply