Úvod
Snažím se zachytit, jaké procesy začaly během omezeného časového období.
Vytvořil jsem skript (ps-suspects.sh
), kde:
- Spouštím
ps-suspects.sh
z terminálu. - Spustím a zavřu aplikaci, řekněme stolní kalkulačku.
- Stisknu Ctrl +C pro ukončení
ps-suspects.sh
- Chci vědět, jaký je název procesu pro kalkulačku
- Nechci vypisovat všechny ostatní názvy procesů, které běží po celou dobu snímku.
Problém
Mám úryvek kódu, který potřebuje doladit:
$ sort -k15 ~/pid.log | uniq -f14 -c
Zde je to, co produkuje:
$ 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
Chci odstranit všechny řádky, které se vyskytují 63
nebo vícekrát.
Požadovaný výstup
$ 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
Otázka
V tomto příkladu 63
se objeví na 90%-99% řádků ve sloupci 1 a tyto řádky je třeba odstranit. Všechny výskyty 126
mohla být také odstraněna. Tedy cokoliv nejčastějšího a většího lze odstranit.
Může někdo přijít s chybějícím awk
a/nebo uniq
a/nebo grep
dokončit úkol?
Přijatá odpověď:
Python na záchranu:
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="")'
Alternativní, nekomprimovaná verze pro použití jako soubor skriptu:
#!/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="")
Jediným předpokladem tohoto skriptu ohledně svého vstupu, od kterého se očekává, že bude přenesen do stdin, je, že každý řádek má ve svém prvním sloupci odděleném mezerami platné celé číslo. Řádky není nutné třídit v žádné formě.
Související:Jaký hashovací algoritmus se používá pro hesla uložená ve stínu v 11.10?Poznámka: Pokud je v prvním sloupci více různých nejběžnějších čísel se stejným počtem, které z těchto dvou bude vybráno, je libovolné, ale mělo by být pro stejný vstup konstantní. V případě, že je to nežádoucí, budete muset nahradit řádek pro zjištění nejběžnější hodnoty něčím takovým, abyste našli nejvyšší nejběžnější hodnotu:
most_common = sorted(collections.Counter(item[0] for item in items).most_common(),
key=lambda x:x[::-1])[-1][0]
Příklad vstupu:
1 foo
3 bar
2 baz
3 apple
3 banana
2 cherry
4 beep
Příklad výstupu:
1 foo
2 baz
2 cherry