More commands to one output file? - linux

I make few commands to parse values from free -m and now need to output all in one file. It looks like this:
free -m | grep 'Mem' | awk '{print $3'} && free -m | grep 'Mem' | awk '{print $6'} && free -m | grep 'Mem' | awk '{print $7'} && free -m | grep 'cache:' | awk '{print $3'}
if I add > /some/file on end, it write only last value, how to write output from all this commands to one file?
thanks for any help

Add parentheses to open a sub shell:
( free -m | grep 'Mem' | awk '{print $3'} && free -m | grep 'Mem' | awk '{print $6'} && free -m | grep 'Mem' | awk '{print $7'} && free -m | grep 'cache:' | awk '{print $3'} ) > result.txt

Related

Getting top urls from an IP address from a nginx log file

I'm after some assistance in getting some stats from an nginx log file. Something is hammering our site and I can see the top ip from this awk command:
sudo awk '{ print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 50
I need to be able to get a list of the urls from this top ip? Can anyone help with the best way to acheive this?
I've got the awk command to lisst the top urls here but need to put them together:
sudo awk '{ print $7}' /var/log/nginx/access.log| sort | uniq -c | sort -nr | head -n 20
Thanks
John
You can use this:
logfile="/var/log/nginx/access.log"
grep "^$(cat "${logfile}" | cut -d' ' -f1 | sort | uniq -c | sort -nr | head -n 1 | awk -F' ' '{print $2}') " "${logfile}" | cut -d' ' -f7 | sort | uniq -c | sort -nr | head -n 50
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

Does not work loop while in bash

I have logs in redmine, about users, that have connected from ip of my server. I can do this via command:
tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | awk '{print $3}' | head -n 1 | tail -n 1
I need to write this parameter in variable.
No problem:
temp=$(tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | awk '{print $3}' | head -n 1 | tail -n 1)
It works. But it can return user name anonymous. To return other user name i should write head -n 2. If it still anonymous, i can change in my formula to head -n 3.
So ... of course i can do this work
#!/bin/bash
temp=$(tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | awk '{print $3}' | head -n 1 | tail -n 1)
if [[ $temp == "anonymous" ]]; then
temp=$(tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | awk '{print $3}' | head -n 2 | tail -n 1)
fi
But it will work for one iteration. I tried to:
while [ $tmp != "anonymous" ]; do
temp=$(tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | awk '{print $3}' | head -n ((var=var+1)) | tail -n 1)
done
But of course it does not work. I can't understand just logically, how can i do this ? Can you help me ? Thanks for your attention.
The immediate problem is that you're setting the variable temp, but checking tmp. You also need double-quotes around the variable in case it's blank, a wildcard, or something else troublesome.
But there's an easier way, because awk can handle most of the work by itself:
tail -n 100000 /usr/share/redmine/log/production.log |
grep -A 3 "192.168.110.50" |
awk '/Current user/ {if ($3 != "anonymous") {print $3; exit}}'
It'd actually be possible to have awk handle looking at the lines after "192.168.110.50" too, but that'd be a little more complicated. BTW, since I don't have any redmine logs (let alone yours) to test with, this has not been properly tested.
You can also use grep -v :
temp=$(tail -n 100000 /usr/share/redmine/log/production.log | grep -A 3 "192.168.110.50" | grep "Current user" | grep -v "anonymous" | awk '{print $3}' | head -n 1 )
Note you don't need final tail -n 1 after head -n 1

wc -m in linux excess 1 value

md5sum file.png | awk '{print $1}' | wc -m
I get: 33
I expect it will return 32 as the length of md5 hash. After read man page and googling I still didn't find out why.
TL;DR
Use awk's length() function:
md5sum file.png | awk '{print length($1)}'
32
It's because awk will add a line feed character to the output. You can check:
md5sum file.png | awk '{print $1}' | xxd
You can tell awk to not doing that using ORS output record separator variable:
md5sum file.png | awk '{print $1}' ORS='' | wc -m
32

Shell script which runs well in terminals not producing expected output in crontab

I'm trying to run a shell script using cron every 15 & 45 mins of the hour. But for some vague reasons it always produces empty strings while executed by cron whereas in when i run using terminals ./my_script.sh it produces expected results. I read many of answers relating to this questions, but none could solve my problem.
codes:
#!/bin/bash
PATH=/bin:/home/mpadmin/bin:/opt/ant/bin:/opt/cc/bin:/opt/cvsconsole:/opt/cvsconsole:/opt/cvsconsole:/sbin:/usr/bin:/usr/lib/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/var/mp/95930/scripts:/var/mp/95930/opt/bin:/opt/prgs/dlc101c/bin:/opt/cvsconsole
tail -n 1000000 conveyor2.log | grep -P 'curingresult OK' | sed 's/FT\ /FT/g' |awk '{print $5 $13}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/master_list.txt
tail -n 1000000 registration.log | grep -P 'TirePresent: 8' | sed 's/GT\ /GT/g' |awk '{print $7 $15}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/TBM_list.txt
my cron
# run 15 and 45 mins every hour, every day
15,47 * * * * sh /var/mp/95910/log/update_master_list.sh
permissions:
all files are having read write and execute permissions for all users
Hope I have given all the relevant & necessary infos
Probably you need to change to the /var/mp/95910/log/ directory first...
#!/bin/bash
cd /var/mp/95910/log/
PATH=/bin:/home/mpadmin/bin:/opt/ant/bin:/opt/cc/bin:/opt/cvsconsole:/opt/cvsconsole:/opt/cvsconsole:/sbin:/usr/bin:/usr/lib/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/var/mp/95930/scripts:/var/mp/95930/opt/bin:/opt/prgs/dlc101c/bin:/opt/cvsconsole
tail -n 1000000 conveyor2.log | grep -P 'curingresult OK' | sed 's/FT\ /FT/g' |awk '{print $5 $13}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/master_list.txt
tail -n 1000000 registration.log | grep -P 'TirePresent: 8' | sed 's/GT\ /GT/g' |awk '{print $7 $15}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/TBM_list.txt
or specify the file paths explicitly
#!/bin/bash
PATH=/bin:/home/mpadmin/bin:/opt/ant/bin:/opt/cc/bin:/opt/cvsconsole:/opt/cvsconsole:/opt/cvsconsole:/sbin:/usr/bin:/usr/lib/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/var/mp/95930/scripts:/var/mp/95930/opt/bin:/opt/prgs/dlc101c/bin:/opt/cvsconsole
tail -n 1000000 /var/mp/95910/log/conveyor2.log | grep -P 'curingresult OK' | sed 's/FT\ /FT/g' |awk '{print $5 $13}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/master_list.txt
tail -n 1000000 /var/mp/95910/log/registration.log | grep -P 'TirePresent: 8' | sed 's/GT\ /GT/g' |awk '{print $7 $15}' |sed 's/\"//g' | uniq | sort -n |uniq > /var/www/html/95910/TBM_list.txt

How to get the name of a person who has maximum age using UNIX commands

I would like to get the name of the person who has maximum age in a unix data file. How can I do this?
Rob,20
Tom,30
I tried this as below but it gives me only max age.
awk -F"," '{print $2}' age.txt | sort -r | head -1
$ cat file | awk -F, '{print $2,$1;}' | sort -n | tail -n1
30 Tom
$ cat file | awk -F, '{print $2,$1;}' | sort -n | tail -n1 | awk '{print $2;}'
Tom
Try perhaps
awk -F, '{if (maxage<$2) { maxage= $2; name=$1; };} END{print name}' \
age.txt
traditional:
sort -t, -nr +1 age.txt | head -1 | cut -d, -f1
POSIXy:
sort -t, -k2,2nr age.txt | head -n 1 | cut -d, -f1
i think you can easily do this using below command
echo -e "Rob,20\nTom,30\nMin,10\nMax,50" | sort -t ',' -rk 2 | head -n 1
Please comment in case of any issues.

Resources