Calculate percentage free swap space with `free` and `awk` - linux

I'm trying to calculate the percentage of free swap space available.
Using something like this:
free | grep 'Swap' | awk '{t = $2; f = $4; print ($f/$t)}'
but awk is throwing:
awk: program limit exceeded: maximum number of fields size=32767
And I don't really understand why, my program is quite simple, is it possible I'm having a weird range error?

Try this one :
free | grep 'Swap' | awk '{t = $2; f = $4; print (f/t)}'
In your code you are trying to print $f and $t which is respectively $FreeMemory and $TotalMemory. So i guess you have about 4gig ram in total which would refer to ~ $400000 which is a little bit over the total of fields awk uses in standard config. Apart from the easier attempt with meminfo try just printing f/t which refers to the variables and you get your answer.

Note that it might be easier/more robust to read the info by using /proc/meminfo's SwapFree line.
Something like:
$ grep SwapFree /proc/meminfo | awk '{print $2}'

You do not need the variables. You can use plain
awk '{ print $4/$2 }'

Read it from /proc/meminfo:
lennart#trololol:~$ grep SwapFree /proc/meminfo | awk '{print $2}'
0

I realise that the question is about using "free" and "awk", but if you have SAR running, then this will give you the most recently recorded percentage value:
sar -S|tail -2|head -1|awk '{print $5}'

Related

Linux/Terminal Grep Total Memory

I want only the number of my total RAM size.
When I try grep MemTotal /proc/meminfo, I get following:
MemTotal: 3943084 kB
But I want only the number, so i need to replace "MemTotal:" and "kB" with "" (nothing).
How to do this in terminal? (Maybe in one line?)
One approach would be
grep MemTotal /proc/meminfo | awk '{print $2;}'
Which "splits" the input at whitespace and displays only the 2nd word.
On more approach, with only awk use
awk '$1~/MemTotal:/ {print $2;}' /proc/meminfo

Is there a command to output only part of a command result in Linux?

My question is, when we type a command with grep in terminal we get output along with the title:
For example:
lscpu | grep MHz
Will output:
CPU MHz: 1216.851
But what if I only want:
1216.851
As the output? Is there any other command to perform this task?
While there are other ways, the most straightforward would probably be awk:
$ lscpu | grep MHz | awk '{print $3}'
2494.038
Or:
$ lscpu | grep MHz | awk '{print $NF}'
2494.038
$3 represents the third field in the output (separated by any amount of whitespace). $NF represents the LAST field in the output, no matter how many fields there are.
You can also skip grep entirely and just do it all with awk:
$ lscpu | awk '/MHz/ { print $NF; exit }'
2494.038
As #glenn jackman pointed out, GNU grep can also do this:
lscpu | grep --color=never -oP 'MHz:\s+\K.*'
But the other examples above are POSIX-friendly (although systems that have lscpu probably also have GNU grep).

How to print all the lines associated to my sorted result in Linux

I have following command that takes a log, sorts it based on the $6 col and makes a unique process on that. At the end, I have just one column as a result.
zgrep 'send_sms_*' logs_new_2015-11.gz |zgrep '^2015-'| zgrep '+1' | awk '{print $6}' | sort | uniq
I need to see all the rest of the lines instead of the just one column after execution of all those commands and I don't know how I have to do it.
Thank you for any help.
I have found the solution, awk is extracting what you ask it to extract and it is losing the rest of the information, so the best way it keep s what we want to have in awk
zgrep 'txt_*' logs_new_2015-11.gz |zgrep '^2015-'| zgrep '+1' | awk '{print $6 " " $0}' | sort | uniq | awk '{$1="";print $0}'
At the end I am removing the first column and I am keeping the rest of the line.
1 awk is enough after a unzip (keeping first zgrep for this purpose)
zgrep 'send_sms_*' logs_new_2015-11.gz \
|awk '/^2015-/&&/\+1/{u[$6]++}END{for(U in u)print U}'
add | sort for sorting if mandatory and basic akw
add BEGIN{PROCINFO["sorted_in"]="#val_str_asc"} as first action in awk action with gawk

Trying to use awk to print a column but says print not found

So I am trying to do some homework and am having a lot of issues. This is the first script I have written in UNIX/Linux. Right now I am trying to print out a few columns from the free command and use awk to just grab those columns I need. Every time I try to do this, i get a bash: print command not found.
Command I am trying to use:
free | awk `{print $3}`
I have also tried without the {}.
So when It is finished I would like it to say for example: Total Free Memory: xx MB
with the xx filled in of course with the result.
Any help is appreciated. Thanks.
UPDATE:
Okay so don't use the backticks to get that to work. So now I would like the whole command to end up saying:
Total Free Memory: xx MB
The command I have so far is:
echo "Current Free Memory: " | free -m | awk '{print $3}'
I only want just that one column row intersection.
You are saying
free | awk `{print $3}`
Whereas you need to say awk '{...}'. That is, use single quotes instead of backticks:
free | awk '{print $3}'
^ ^
Note this is explained in man awk:
Syntax
awk <options> 'Program' Input-File1 Input-File2 ...
awk -f PROGRAM-FILE <options> Input-File1 Input-File2 ...
You should go for the field 4.
As I suggest using awk and sed but it is up to you.
Here is my suggestion :
freem="$(free -m | awk '{print $4}' | sed -n '2p')"
echo "Total Free Memory: $freem MB"
Where $4 is the columns you want and 2p is the line you want.
Before writing the script, check your result in command line.
free -m | awk '/Mem:/ {print "Current Free Memory: " $4 " MB"}'

Simpler way of extracting text from file

I've put together a batch script to generate panoramas using the command line tools used by Hugin. One interesting thing about several of those tools is they allow multi-core usage, but this option has to be flagged within the command.
What I've come up with so far:
#get the last fields of each line in the file, initialize the line counter
results=$(more /proc/cpuinfo | awk '{print ($NF)}')
count=0
#loop through the results till the 12th line for cpu core count
for result in $results; do
if [ $count == 12 ]; then
echo "Core Count: $result"
fi
count=$((count+1))
done
Is there a simpler way to do this?
result=$(awk 'NR==12{print $NF}' /proc/cpuinfo)
To answer your question about getting the first/last so many lines, you could use head and tail,e.g. :
cat /proc/cpuinfo | awk '{print ($NF)}' | head -12 | tail -1
But instead of searching for the 12th line, how about searching semantically for any line containing cores. For example, some machines may have multiple cores, so you may want to sum the results:
cat /proc/cpuinfo | grep "cores" | awk '{s+=$NF} END {print s}'
count=$(getconf _NPROCESSORS_ONLN)
see getconf(1) and sysconf(3) constants.
According to the Linux manpage, _SC_NPROCESSORS_ONLN "may not be standard". My guess is this requires glibc or even a Linux system specifically. If that doesn't work, I'd probably take looking at /sys/class/cpuid (perhaps there's something better?) over parsing /proc/cpuinfo. None of the above are completely portable.
There are many ways:
head -n 12 /proc/cpuinfo | tail -1 | awk -F: '{print $2}'
grep 'cpu cores' /proc/cpuinfo | head -1 | awk -F: '{print $2}'
and so on.
But I must note that you take only the information from the first section of /proc/cpuinfo and I am not sure that that is what you need.
And if the cpuinfo changes its format ;) ? Maybe something like this will be better:
cat /proc/cpuinfo|sed -n 's/cpu cores\s\+:\s\+\(.*\)/\1/p'|tail -n 1
And make sure to sum the cores. Mine has got like 12 or 16 of them ;)
unsure what you are trying to do and why what ormaaj said above wouldn't wouldn't work either. my instinct based on your description would have been much simpler along the lines of.
grep processor /proc/cpuinfo | wc -l

Resources