Does not work loop while in bash - linux

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

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

Find the highest number inside a file

I am trying to find the highest number inside a string from a file. For example, in the file password.txt we have:
jaime:45:/home/jaime:/bin/bash
sofia:113:/home/sofia:/bin/bash
marta:2015:/home/marta:/bin/bash
pedro:2024:/home/pedro:/bin/bash
So the highest number should be 2024 and we have to save it into a variable:-
number=2024
I've tried several things with grep, awk, sed or even with sort, but without any solution.
I suggest:
number=$(cut -d: -f 2 file | sort -n | tail -n 1)
Awk to the rescue!
awk -F":" 'BEGIN{max=0}{if(($2)>max) max=$2}END {print max}' file
2024
To save it in a variable,
max="$( awk -F":" 'BEGIN{max=0}{if(($2)>max) max=$2}END {print max}' file)"
printf "%d\n" "$max"
2024
Try this:
number=$(grep -o '[0-9]*' password.txt | sort -nr | head -1)
#Thotensar: If your Input_file is same as shown as sample Input, then following may help you in same.
awk -F":" '{Q=Q>$2?Q:$2} END{print Q}' Input_file
I hope this helps you.
Fahrad his answer gives me the expected result in some other context of finding the highest amount of a range of amounts, in order to use it for percentage calculation afterwards:
cat $(dirname "$0")/wordcount.txt | xargs -n 1 | sort -g | uniq -c | paste -s --delimiters=";" | tr -s ' ' 'x' | sed 's/;x/; /g' | sed 's/x/ x /g' | cut -c 4- > $(dirname "$0")/wordcount_temp.txt
RESULT=$(cat $(dirname "$0")/wordcount_temp.txt)
echo "$RESULT"
echo
MAXIMUM=$(grep -Eo '[0-9]{1,} x' $(dirname "$0")/wordcount_temp.txt | sort -nr | head -1 | sed 's/ x//g')
echo "$MAXIMUM"
Gives:
12 x 0; 14 x 1; 17 x 2; 7 x 3; 3 x 4; 8 x 5; 11 x 6; 18 x 7; 9 x 8; 13 x 9
18
Thank you.

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.

How i can find top 5 processes that spawn off the most number of child processes

How i can find top 5 processes that spawn off the most number of child processes.
Only direct children:
pids=`ps hx | awk '{print $1}' | grep -v '^1$'`
(for p in $pids; do echo -n $p ""; ps h --ppid $p | wc -l; done) | sort -k 2 -r | head -n 5
If you are looking for children of the children as well:
pids=`ps hx | awk '{print $1}' | grep -v '^1$'`
(for p in $pids; do echo -n $p ""; pstree $p 2>/dev/null | wc -l; done) | sort -n -k 2 -r | head -n 5
Example (first number is PID, the second one is number of children + 1(parent)):
2 121
2624 12
2933 4
30514 3
2634 3
With luck, it suffices to look for the top 5 parent pids in ps.

Resources