How to kill all processes of the same name but keep the latest one running? - awk

I've seen this but I can't quite figure out how to kill all processes of a given name but keep the most recent one running.
So for example, this will show me the running processes:
$ ps -eo pid,etime,comm | grep maya.bin
23752 10:40 maya.bin
23841 12:04 maya.bin
23891 14:46 maya.bin
Somehow, I would need to filter out the PIDs 23752 23841 (but not 23891) and kill those.
If I could just figure out how to find those PIDs, presumably via awk, I could kill via e.g.
ps -eo pid,etime,comm | awk ??? | kill -9
or
kill -9 $(ps aux | grep 'maya.bin' | awk ??? )
Is this possible using awk?

If I understand correctly, you need to select the first word and then all but the last row. You can do that with
awk '{ print $1 }' | head -n -1
The total command would then be
kill -9 $(ps aux | grep 'maya.bin' | awk '{ print $1 }' | head -n -1)

Related

Better way to process dmidecode data using awk/sed

I run
dmidecode -t 4 | awk '/Signature/,/L1 Cache Handle/' |
grep -e 'Signature' -e 'L1 Cache Handle' |
awk -v Model="$4" '{
if ($4 == "Model")
print $5 " " $7;
else if ($1 == "L1")
print " " $4}' >> data
The contents of 'data' on my system is :
49, 0
0x002E
Essentially, 'data' corresponds to :
Signature: Family 23, Model 49, Stepping 0
L1 Cache Handle: 0x002E
(Model # and L1 cache handle)
Looking for a better/efficient way to do the above operation. Thanks.
Would you please try the following:
dmidecode -t 4 | sed -nE '/Signature|L1 Cache Handle/{s/.*Model ([0-9]+), Stepping ([0-9]+).*/\1 \2/p;s/.*L1 Cache Handle: ([0-9A-Za-z])/\1/p}' | xargs
The sed command extracts the values for Model, Stepping and
L1 Cache Handle:.
The final xargs merges two lines into one.

printf usage with awk when printing multiple columns

I am trying this below command:
cat dcl1serrfip_check.csv | grep -Fi 'BANK0_F5_WRDAT_P0[0]' | grep -i setup | grep 'L2H' | grep highv | grep -i low | awk -F ',' -v dev="0.861" -v rc="1.105" -v inte="0.872" '{ print ($10+$11)-(($12+$13)-($14))","($10*dev)+($11*rc)-(($12*dev)+($13*rc)-($14*inte))}'
This gives below output:
-6.93889e-18,0.000288
I want this output to be formatted to 4 decimal places. How to do it? The desired output would be
-0.0000,0.0002
You need, %0.4f or %.4f
To Test use :
awk 'BEGIN{ printf("%0.4f\n", -6.93889e-18) }'
So it becomes:
printf("%0.4f,%0.4f\n", ($10+$11)-(($12+$13)-($14)), ($10*dev)+($11*rc)-(($12*dev)+($13*rc)-($14*inte)) )
Actually you can rewrite your command in awk itself, no need of so many grep and cat combination

awk, how to pass in a list of files based on a condition?

I was wondering if there is any way to pass in a file list to awk. The file list has thousands of files and I am using a grep -l to find a subset of files I am interested in passing to awk
E.g.,
grep -l id file-*.csv
file-1.csv
file-2.csv
$ cat file-1.csv
id,col_1,col_2
1,abc,100
2,def,200
$ cat file-2.csv
id,col_1,col_2
3,xyz,1000
4,hij,2000
If I do
$ awk -F, '{print $2,$3}' file-1.csv file-2.csv | grep -v col
abc 100
def 200
xyz 1000
hij 2000
it works how I would want but seeing as there are too many files to manually do like this
file-1.csv file-2.csv
I was wondering if there is a way to pass in the result of the...
grep -l id file-*.csv
Edit:
grep -l id
is the condition. Each file has a header but only some have 'id' in the header so I can't use the file-*.csv wildcard in the awk statement.
If I did an ls on file-*.csv I would end up with more the file-1.csv and file-2.csv.
e.g.,
$ cat file-3.csv
name,col,num
a1,hij,3000
b2,lmn,50000
$ ls -l file-*.csv
-rw-r--r-- 1 tp staff 35 20 Sep 18:50 file-1.csv
-rw-r--r-- 1 tp staff 37 20 Sep 18:51 file-2.csv
-rw-r--r-- 1 tp staff 38 20 Sep 18:52 file-3.csv
$ grep -l id file-*.csv
file-1.csv
file-2.csv
Based on the output you show under "If I do", it sounds like this might be what you're trying to do:
awk -F, 'FNR>1{print $2,$3}' file-*.csv
but your question isn't clear so it's a guess.
Given your updated question all you need with GNU awk for nextfile is:
awk -F, 'FNR==1{if ($1 != "id") nextfile} {print $2,$3}' file-*.csv
and with any awk (but less efficiently than with GNU awk):
awk -F, 'FNR==1{f=($1=="id"?1:0); next} f{print $2,$3}' file-*.csv
awk -F, 'NR > 1{print $2,$3}' $(grep -l id file-*.csv)
(This will not work if any of your filenames contain whitespace.)
To find the files with id field, merge/output their contents excluding the lines with field id:
grep trick:
grep --no-group-separator -hA 1000000 'id' file-*.csv | grep -v 'id'
-h - suppress the prefixing the file names on output
-A num - print num lines of trailing context after matching line(s). 1000000 - considered as maximal number of line which, presumably, will not be exceeded(you may adjust it in case if you really have files with more than 1000000 lines)
The output (for 2 sample files from the question):
1,abc,100
2,def,200
3,xyz,1000
4,hij,2000

Add text to beginning of awk result

Good day all,
I am running below command:
netstat -an | awk '/:25/{ print $4 }' | sed 's/:25//' | paste -sd ',' -
which produces
192.168.2.22,127.0.0.1
I would like to amend the result to something like below (to be parsed as a csv by an application)
Manuallyaddedtext 192.168.2.22,127.0.0.1
Many thanks
echo -n "Mytext " ; netstat...

Awk last field string substitution

I am trying to get the last filed using string substiution of following output using awk -
ps -ef |grep -i "[o]cssd.bin"
Output:
grid 47275 1 1 Sep23 ? 17:49:39 /opt/grid/12.1/bin/ocssd.bin
used awk as -
$ ps -ef | grep -i "[o]cssd.bin" | awk '{ gsub("/ocssd.bin",""); print $NF}'
output:
$NF}
/opt/grid/12.1/bin
How to avoid "$NF}" ? I only need "/opt/grid/12.1/bin" ..!
try:
ps -ef | grep -i "[o]cssd.bin" | awk '{ if(gsub("/ocssd.bin","")) print $NF}'