web-dev-qa-db-fra.com

Renvoie uniquement la partie d'une ligne après un motif correspondant

Donc, ouvrir un fichier avec cat puis utiliser grep pour obtenir des lignes correspondantes ne me permet de me rendre jusque-là que lorsque je travaille avec le jeu de journaux particulier que je traite. Il a besoin d'un moyen de faire correspondre les lignes à un modèle, mais uniquement de renvoyer la partie de la ligne après la correspondance. La portion avant et après le match variera constamment. J'ai joué avec sed ou awk, mais je n'ai pas réussi à filtrer la ligne pour supprimer la partie avant le match ou simplement renvoyer la partie après le match, l'un ou l'autre fonctionnera. Voici un exemple de ligne que je dois filtrer:

2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.AMD64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }

La portion dont j'ai besoin est tout après "calé".

Le contexte derrière cela est que je peux savoir à quelle fréquence quelque chose cale:

cat messages | grep stalled | wc -l

Ce que je dois faire est de savoir combien de fois un certain nœud a bloqué (indiqué par la portion avant chaque deux points après "bloqué". pas de décrochage, ce qui ne m'aide pas. J'ai besoin de filtrer uniquement la partie bloquée pour pouvoir ensuite rechercher un nœud spécifique parmi ceux qui ont calé.

À toutes fins utiles, il s'agit d'un système freebsd avec les utilitaires standard GNU core, mais je ne peux rien installer de plus pour vous aider.

127
MaQleod

L'outil canonique pour cela serait sed.

sed -n -e 's/^.*stalled: //p'

Explication détaillée:

  • -n Signifie ne rien imprimer par défaut.
  • -e Est suivi d'une commande sed.
  • s est la commande de remplacement de modèle.
  • L'expression régulière ^.*stalled: Correspond au modèle que vous recherchez, plus tout texte précédent (.* Signifiant tout texte, avec un ^ Initial pour indiquer que la correspondance commence au début de la ligne). Notez que si stalled: Se produit plusieurs fois sur la ligne, cela correspondra à la dernière occurrence.
  • La correspondance, c'est-à-dire tout sur la ligne jusqu'à stalled:, Est remplacée par la chaîne vide (c'est-à-dire supprimée).
  • Le dernier p signifie imprimer la ligne transformée.

Si vous souhaitez conserver la partie correspondante, utilisez une référence arrière: \1 Dans la pièce de rechange désigne ce qui se trouve à l'intérieur d'un groupe \(…\) dans le motif. Ici, vous pouvez réécrire stalled: Dans la pièce de rechange; cette fonction est utile lorsque le motif que vous recherchez est plus général qu'une simple chaîne.

sed -n -e 's/^.*\(stalled: \)/\1/p'

Parfois, vous souhaiterez supprimer la partie de la ligne après le match. Vous pouvez l'inclure dans la correspondance en incluant .*$ À la fin du motif (tout texte .* Suivi de la fin de la ligne $). Sauf si vous placez cette partie dans un groupe auquel vous faites référence dans le texte de remplacement, la fin de la ligne ne sera pas dans la sortie.

Comme illustration supplémentaire des groupes et des références arrières, cette commande échange la partie avant la correspondance et la partie après la correspondance.

sed -n -e 's/^\(.*\)\(stalled: \)\(.*\)$/\3\2\1/p'

L'autre outil canonique que vous utilisez déjà: grep:

Par exemple:

grep -o 'stalled.*'

A le même résultat que la deuxième option de Gilles:

sed -n -e 's/^.*\(stalled: \)/\1/p'

Le -o flag renvoie le --only-matching une partie de l'expression, donc pas la ligne entière qui est - bien sûr - normalement effectuée par grep.

Pour supprimer le "bloqué:" de la sortie, nous pouvons utiliser un troisième outil canonique, couper:

grep -o 'stalled.*' | cut -f2- -d:

La commande cut utilise le délimiteur : et imprime le champ 2 jusqu'à la fin. C'est une question de préférence bien sûr, mais la syntaxe cut que je trouve très facile à retenir.

83
Anne van Rossum

J'ai utilisé ifconfig | grep eth0 | cut -f3- -d: pour prendre ça

    [root@MyPC ~]# ifconfig
    eth0  Link encap:Ethernet  HWaddr AC:B4:CA:DD:E6:F8
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:78998810244 errors:1 dropped:0 overruns:0 frame:1
          TX packets:20113430261 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:110947036025418 (100.9 TiB)  TX bytes:15010653222322 (13.6 TiB)

et le faire ressembler à ceci

    [root@MyPC ~]# ifconfig | grep eth0 | cut -f3- -d:
    C4:7A:4D:F6:B8
4
Luis Perez

Encore un autre outil canonique que vous considérez awk pourrait être utilisé avec la ligne suivante:

awk -F"stalled" '/stalled/{print $2}' messages

Explication détaillée:

  • -F définit un séparateur pour la ligne, c'est-à-dire "bloqué". Tout avant le séparateur est traité par $1 et tout après avec $2.
  • /reg-ex/ Recherche l'expression régulière correspondante, dans ce cas "bloqué".
  • {print $<n>} - imprime la colonne n. Étant donné que votre séparateur est défini comme bloqué, tout ce qui est bloqué est considéré comme la deuxième colonne.
3
robertm.tum

il semble d'une manière plus simple. fais juste:

sed "s/installed.*//g"

qui supprime tous les mots après "installé".

for i in *
do
    se=$(echo $i|sed "s/---.*//g")
    echo $se
    mv "$i" $se
done
0
minor hash