Use Shell script to retrieve max number of users' activity in a file - shell

Given a /var/log/messages file as below that recording different users sending Emails records, for example:
20140912 chris sendingemails_id00012jjdi3x
20140912 chris sendingemails_id00012jjdiji
20140912 alen sendingemails_id00012jwciscl
20140914 chris sendingemails_id00012jjdiji
20140915 linda sendingemails_id042555jwciscl
20140915 chris sendingemails_id00012jjdiji
20140916 alen sendingemails_id005hhbxxsscl
20140917 chris sendingemails_id2221d2rwaaiji
20140917 linda sendingemails_id00012baseeqcl
20140918 chris sendingemails_id45677tehhwaaiji
Now, I need to retrieve the user who sends emails the most. How can I do it?
Thanks a lot.

This should help:
cat /var/log/messages | grep "sendingemails_" | awk '{print $2}' | sort | uniq -c
OR to get exactly the username:
cat /var/log/messaes | grep "sendingemails_" | awk '{print $2}' | sort | uniq -c | sort -r | head -1 | awk '{print $2}'

Related

Why is the RX and TX values ​the same when executing the network packet statistics script on centos8?

##test1 on rhel8 or centos8
$for i in 1 2;do cat /proc/net/dev | grep ens192 | awk '{print "RX:"$2"\n""TX:"$10}';done | awk '{print $0}' | tee 111
##result:
RX:2541598118
TX:1829843233
RX:2541598118
TX:1829843233

How to sort data according to the date in bash?

I need to write a bash program that sorts the data according to the date and displays the name of the person who recently joined the organization.
I have an employees.txt file with data in it with delimiter |. But when I am trying to sort the data using sort command like
sort -t'|' -k5,5 employees.txt | head -1 | cut -d'|' -f2
this is only sorting according to the first column of the whole date i.e DD-MM-YYYY sorting only on DD.
employees.txt File data format
ID | NAME | POST | DEPARTMENT | JOINING DATE | SALARY
101 | Jhon McClare | Manager | Content | 23-02-2001 | 83000
102 | Alena Croft | Snr. Manager | Accounts | 01-01-2019 | 88888
103 | Jeremy | Director | Sales | 20-03-2012 | 89786
104 | Williams | Manager | Marketing | 23-06-2001 | 73000
The above image should give Alena Croft as the answer.
The relevant field be must rendered suitable for sorting, that is, in the form of YYYY-MM-DD, using a utility such as sed or awk. For example, with GNU sed:
sed -E 's/([0-9]{2})-([0-9]{2})-([0-9]{4})/\3-\2-\1/' employees.txt |
sort -r -t'|' -k5,5 | head -n1 | cut -d'|' -f2
The trick is to change the format of date to YYYY-MM-DD.
$ cat people.txt | sed -E 's/([0-9]+)\-([0-9]+)\-([0-9]+)/\3\-\2\-\1/' | sort -t'|' -k5,5r | head -1 | cut -d'|' -f2
Alena Croft
Also note that when sorting we need to do in reverse order (descending order) since we want the most recent date.

From awk output, how to cut or trim characters in columns

At the moment
I want to trim .fmbi1a5nn9sp5o4qy3eyazeq5.eddvrl9sa8t448pb38vibj8ef: and .ilwio0k43fgqt4jqzyfadx19v: so the output take less space :)
First step:
docker ps --format "{{.Names}}: {{.Status}}" | sort -k1 | column -t
mon_node-exporter.fmbi1a5nn9sp5o4qy3eyazeq5.eddvrl9sa8t448pb38vibj8ef: Up 7 days
mon_prometheus.1.ilwio0k43fgqt4jqzyfadx19v: Up 7 days
I know
I can do something like:
docker ps --format "{{.Names}}: {{.Status}}" | sort -k1 | rev | cut -d"." -f2- | rev
mon_node-exporter.fmbi1a5nn9sp5o4qy3eyazeq5
mon_prometheus.1
The issue
is that I'm losing the other columns :-/
Idea
It would sound logical to do something like this (with awk) but it does not work. Any ideas?
docker ps --format "{{.Names}} : {{.Status}}" | sort -k1 | awk '{(print $1 | rev | cut -d"." -f2- | rev),$2,$3,$4,$5,$6}' | column -t
Thank you in advance!
P
to cut the last dot extension
$ docker ... | sort | awk '{sub(/\.[^.]*$/,"",$1)}1' file | column -t
mon_node-exporter.fmbi1a5nn9sp5o4qy3eyazeq5 Up 7 days
mon_prometheus.1 Up 7 days
or, delete anything longer than 20 chars after a dot.
$ ... | sed -e 's/\(\.[a-z0-9:]\{20,\}\)* / /' | column -t
mon_node-exporter Up 7 days
mon_prometheus.1 Up 7 days
Works! This trick will make my life so much easier.
(I removed file)
docker ps --format "{{.Names}}: {{.Status}}" | sort -k1 | awk '{sub(/\.[^.]*$/,"",$1)}1' | column -t;
mon_grafana.1 Up 24 hours
mon_node-exporter.fmbi1a5nn9sp5o4qy3eyazeq5 Up 23 hours
Question #2:
Now how would you proceed to cut the characters after the first dot?
Cheers!

How do I print a different variable dependent on multiple quantity variables (and math)?

Source File Input (.csv):
TOTAL FULL PARTIALORDER FULLORDER DEVICENAME
10 2 123456 456789 OHWIL8499IPM101
8 0 345678 789605 OHCIN8499IPM102
TOTAL= Is the total number of devices for a full and partial order.
FULL = A different order but of same location.
PARTIAL/FULL ORDER = Order numbers. I need to print one after each device name.
Requirement/Goal:
I need to subtract FULL from TOTAL. If there is a difference I need to change the order number variable on the last (# OF FULL) device names printed.
If there are 10 total and 2 full I need 8 devices printed OHWIL8499IPM101 through OHWIL8499IPM108 followed by the partial order number. Then OHWIL8499IPM109-110 followed by the full order number. In the input file example above the second line doesn't have a difference so I only need to print the partial order number.
Desired Output File (.csv):
DEVICENAME ORDERNUMBER SHIPDATE TYPE SYSTEMSKU
OHWIL8499IPM101 123456 ASAP PROJECT1 12345678
OHWIL8499IPM102 123456 ASAP PROJECT1 12345678
OHWIL8499IPM103 123456 ASAP PROJECT1 12345678
OHWIL8499IPM104 123456 ASAP PROJECT1 12345678
OHWIL8499IPM105 123456 ASAP PROJECT1 12345678
OHWIL8499IPM106 123456 ASAP PROJECT1 12345678
OHWIL8499IPM107 123456 ASAP PROJECT1 12345678
OHWIL8499IPM108 123456 ASAP PROJECT1 12345678
OHWIL8499IPM109 456789 ASAP PROJECT1 12345678
OHWIL8499IPM110 456789 ASAP PROJECT1 12345678
Current Script:
#!/bin/bash
currentUser=$(/bin/ls -la /dev/console | /usr/bin/cut -d ' ' -f 4)
LOGFILE="/Users/$currentUser/Desktop/kit.csv"
SRCFILE="/Users/$currentUser/Desktop/input.csv"
orderFull=$(cat "$SRCFILE" | sed 's/,/ /g' | awk '{print $4}')
orderPartial=$(cat "$SRCFILE" | sed 's/,/ /g' | awk '{print $3}')
device_name=$(cat "$SRCFILE" | sed 's/,/ /g' | awk '{print $5}')
quantityNum=$(cat "$SRCFILE" | sed 's/,/ /g' | awk '{print $1}')
quantityFull=$(cat "$SRCFILE" | sed 's/,/ /g' | awk '{print $2}')
shipDate=ASAP
projectType=Project1
systemSku=1235678
number=$(echo "$device_name" | head -c 9| tail -c 4)
max_sequence_name=$()
max_sequence_num=$(echo $max_sequence_name | rev | cut -c 1-3 | rev)
if [ -z "$max_sequence_name" ];
then
max_sequence_name=device_name
max_sequence_num=100
fi
array_new_sequence_name=()
for i in $(seq 1 $quantityNum);
do
cnum=$((max_sequence_num + i))
array_new_sequence_name+=($(echo $device_name$cnum))
done
for sqn in ${array_new_sequence_name[#]};
do
echo "$sqn,$orderNumber,$shipDate,$projectType,$systemSku,$number" >> $LOGFILE
done
So far I have the following code I've been attempting to start with but am unsure if I'm on the right track or not.
if [ "$quantityFull" = 0 ]; then
orderNumber=$(echo "$orderPartial")
else
math=$(expr $orderPartial - $orderFull)
#ENTER CODE HERE TO DETERMINE WHICH NAMES TO CHANGE ORDER NUMBER ON
orderNumber=$(echo "$orderFull")
fi
Once this can be determined where would I place it in the above script? Or is there an easier way of implementing this somehow? If you need additional information please let me know.

Cleaning up IP output on command line [duplicate]

This question already has answers here:
How to clean up masscan output (-oL)
(4 answers)
Closed 6 years ago.
I have a problem with the output L options ("grep-able" output); for instance, it outputs this:
| 14.138.12.21:123 | unknown | disabled |
| 14.138.184.122:123 | unknown | disabled |
| 14.138.179.27:123 | unknown | disabled |
| 14.138.20.65:123 | unknown | disabled |
| 14.138.12.235:123 | unknown | disabled |
| 14.138.178.97:123 | unknown | disabled |
| 14.138.182.153:123 | unknown | disabled |
| 14.138.178.124:123 | unknown | disabled |
| 14.138.201.191:123 | unknown | disabled |
| 14.138.180.26:123 | unknown | disabled |
| 14.138.13.129:123 | unknown | disabled |
The above is neither very readable nor easy to understand.
How can I use Linux command-line utilities, e.g. sed, awk, or grep, to output something as follows, using the file above?
output
14.138.12.21
14.138.184.122
14.138.179.27
14.138.20.65
14.138.12.235
Using awk with field separator as space, and : and getting the second field:
awk -F '[ :]' '{print $2}' file.txt
Example:
% cat file.txt
| 14.138.12.21:123 | unknown | disabled |
| 14.138.184.122:123 | unknown | disabled |
| 14.138.179.27:123 | unknown | disabled |
| 14.138.20.65:123 | unknown | disabled |
| 14.138.12.235:123 | unknown | disabled |
| 14.138.178.97:123 | unknown | disabled |
| 14.138.182.153:123 | unknown | disabled |
| 14.138.178.124:123 | unknown | disabled |
| 14.138.201.191:123 | unknown | disabled |
| 14.138.180.26:123 | unknown | disabled |
| 14.138.13.129:123 | unknown | disabled |
% awk -F '[ :]' '{print $2}' file.txt
14.138.12.21
14.138.184.122
14.138.179.27
14.138.20.65
14.138.12.235
14.138.178.97
14.138.182.153
14.138.178.124
14.138.201.191
14.138.180.26
14.138.13.129
AWK is perfect for cases when you want to split the file by "columns", and you know exactly that the order of values/columns is constant. AWK splits the lines by a field separator (which can be a regular expression like '[: ]'). The column names are accessible by their positions from the left: $1, $2, $3, etc.:
awk -F '[ :]' '{print $2}' src.log
awk -F '[ :|]' '{print $3}' src.log
awk 'BEGIN {FS="[ :|]"} {print $3}' src.log
You can also filter the lines with a regular expression:
awk -F '[ :]' '/138\.179\./ {print $2}' src.log
However, it is impossible to capture substrings with the regular expression groups.
SED is more flexible in regard to regular expressions:
sed -r 's/^[^0-9]*([0-9\.]+)\:.*/\1/' src.log
However, it lacks many useful features of the Perl-like regular expressions we used to use in every day programming. For example, even the extended syntax (-r) fails to interpret \d as a number.
Perhaps, Perl is the most flexible tool for parsing files. You can opt to simple expressions:
perl -n -e '/^\D*([^:]+):/ and print "$1\n"' src.log
or make the matching as strict as you like:
perl -n -e '/^\D*((?:\d{1,3}\.){3}\d{1,3}):/ and print "$1\n"' src.log
using sed
sed -r 's/^ *[|] *([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+):[0-9]{3}.*/\1/

Resources