Introduzione
Sto cercando di acquisire quali processi sono stati avviati in un periodo di tempo limitato.
Ho creato uno script (ps-suspects.sh
) dove:
- Eseguo
ps-suspects.sh
dal terminale. - Avvio e chiudo un'applicazione, diciamo la Calcolatrice desktop.
- Premo Ctrl +C per terminare
ps-suspects.sh
- Voglio sapere qual è il nome del processo per la Calcolatrice
- Non voglio un elenco di tutti gli altri nomi di processi che eseguono l'intero periodo dello snapshot.
Il problema
Ho uno snippet di codice che deve essere messo a punto:
$ sort -k15 ~/pid.log | uniq -f14 -c
Ecco cosa produce:
$ head ~/pid.tmp
1 /mnt/e/bin/ps-suspects.sh Possible suspects causing problems
63 1 S root 127 2 0 60 -20 - 0 - Sep08 ? 00:00:00 [acpi_thermal_pm]
63 1 S root 75 2 0 60 -20 - 0 - Sep08 ? 00:00:00 [ata_sff]
63 1 S root 447 2 0 60 -20 - 0 - Sep08 ? 00:00:00 [ath10k_aux_wq]
63 1 S root 446 2 0 60 -20 - 0 - Sep08 ? 00:00:00 [ath10k_wq]
63 1 S avahi 922 910 0 80 0 - 11195 - Sep08 ? 00:00:00 avahi-daemon: chroot helper
63 4 S avahi 910 1 0 80 0 - 11228 - Sep08 ? 00:00:00 avahi-daemon: running [alien.local]
126 0 S rick 2902 2867 0 80 0 - 7409 wait_w Sep08 pts/18 00:00:00 bash
63 0 S rick 25894 5775 0 80 0 - 4908 wait 10:43 pts/2 00:00:00 /bin/bash /mnt/e/bin/ps-suspects.sh
63 0 S root 980 976 0 80 0 - 4921 - Sep08 ? 00:00:01 /bin/bash /usr/local/bin/display-auto-brightness
Voglio eliminare tutte le righe che si verificano 63
o più volte.
Uscita desiderata
$ ps-suspects.sh
20 times / second ps -elf is captured to /home/rick/pid.log
Type Ctrl+C when done capturing
~/pid.log is sorted and uniq counted on column 15
which is full path and program name.
Then all matches with same unique count (the headings)
are stripped and only new processes started are printed.
This function can help you trace down what processes are
causing you grief for lid close events, hot plugging, etc.
^C
wc of ~/pid.log : 17288 343162 2717102 /home/rick/pid.log
HighCnt: 63
1 /mnt/e/bin/ps-suspects.sh Possible suspects causing problems
26 0 R rick 25976 2051 0 80 0 - 120676 - 10:43 ? 00:00:00 gnome-calculator
62 0 S root 22561 980 0 80 0 - 3589 - 10:42 ? 00:00:00 sleep 60
Domanda
In questo esempio 63
apparirà sul 90% -99% delle righe nella colonna 1 e quelle righe devono essere rimosse. Tutte le occorrenze di 126
potrebbe anche essere rimosso. Quindi qualsiasi cosa più frequente e più grande può essere rimosso.
Qualcuno può trovare il awk
mancante e/o uniq
e/o grep
per finire l'attività?
Risposta accettata:
Python in soccorso:
python3 -c 'import sys,collections;l=[(int(L.split(None,1)[0]),L)for L in sys.stdin.readlines()];m=collections.Counter(x[0]for x in l).most_common(1)[0][0];print(*[x[1]for x in l if x[0]<m],sep="",end="")'
Versione alternativa non compressa da utilizzare come file di script:
#!/usr/bin/env python3
import sys
import collections
# read lines from stdin (with trailing \n) and extract the number in their first column
items = [(int(line.split(None, 1)[0]), line) for line in sys.stdin]
# find the most common number from the first column
most_common = collections.Counter(item[0] for item in items).most_common()[0][0]
# print input lines in order, but only those with their number lower than the most common
print(*[item[1] for item in items if item[0] < most_common], sep="", end="")
L'unico presupposto che questo script fa sul suo input, che dovrebbe essere reindirizzato a stdin, è che ogni riga abbia un numero intero valido nella sua prima colonna separata da spazi bianchi. Le righe non devono essere ordinate in alcun modo.
Correlati:quale algoritmo hash viene utilizzato per le password archiviate in shadow in 11.10?Nota: Se nella prima colonna sono presenti più numeri più comuni diversi con lo stesso conteggio, quale di questi due viene selezionato è arbitrario, ma dovrebbe essere costante per lo stesso input. Nel caso in cui ciò non sia desiderato, dovresti sostituire la riga che trova il valore più comune con qualcosa di simile, invece, per trovare il valore più comune più alto:
most_common = sorted(collections.Counter(item[0] for item in items).most_common(),
key=lambda x:x[::-1])[-1][0]
Esempio di input:
1 foo
3 bar
2 baz
3 apple
3 banana
2 cherry
4 beep
Esempio di output:
1 foo
2 baz
2 cherry