Présentation
J'essaie de capturer quel(s) processus ont commencé sur une période de temps limitée.
J'ai créé un script (ps-suspects.sh
) où :
- Je lance
ps-suspects.sh
depuis le terminal. - Je démarre et ferme une application, par exemple la calculatrice de bureau.
- J'appuie sur Ctrl +C pour terminer
ps-suspects.sh
- Je veux savoir quel est le nom du processus pour la calculatrice
- Je ne veux pas une liste de tous les autres noms de processus exécutés sur toute la période de l'instantané.
Le problème
J'ai un extrait de code à peaufiner :
$ sort -k15 ~/pid.log | uniq -f14 -c
Voici ce qu'il produit :
$ 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
Je veux éliminer toutes les lignes qui apparaissent 63
ou plusieurs fois.
Sortie souhaitée
$ 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
Question
Dans cet exemple 63
apparaîtra sur 90 % à 99 % des lignes de la colonne 1 et ces lignes doivent être supprimées. Toutes les occurrences de 126
pourrait également être supprimé. Donc, tout ce qui est le plus fréquent et le plus important peut être supprimé.
Quelqu'un peut-il trouver le awk
manquant et/ou uniq
et/ou grep
terminer la tâche ?
Réponse acceptée :
Python à la rescousse :
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="")'
Version alternative non compressée à utiliser comme fichier de 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="")
La seule hypothèse que ce script fait à propos de son entrée, qui devrait être redirigée vers stdin, est que chaque ligne a un nombre entier valide dans sa première colonne séparée par des espaces. Les lignes n'ont pas besoin d'être triées sous quelque forme que ce soit.
En relation :Quel algorithme de hachage est utilisé pour les mots de passe stockés dans shadow dans 11.10 ?Remarque : S'il y a plusieurs nombres différents les plus courants dans la première colonne avec le même nombre, lequel de ces deux est sélectionné est arbitraire, mais doit être constant pour la même entrée. Au cas où cela ne serait pas souhaité, vous devrez remplacer la ligne trouvant la valeur la plus courante par quelque chose comme ceci à la place, pour trouver la valeur la plus courante la plus élevée :
most_common = sorted(collections.Counter(item[0] for item in items).most_common(),
key=lambda x:x[::-1])[-1][0]
Exemple d'entrée :
1 foo
3 bar
2 baz
3 apple
3 banana
2 cherry
4 beep
Exemple de sortie :
1 foo
2 baz
2 cherry