1 votes

Appliquer les opérations sed uniquement aux lignes commençant par une chaîne particulière

J'ai le format de fichier suivant

Received from +11231231234 at 2021-10-10T19:56:50-07:00:
This is a message that contains words like from, at, etc.

Sent to +11231231234 at 2021-10-11T06:50:57+00:00:
This is another message that contains words like to, at, etc.

Je veux nettoyer les lignes "Received" et "Sent", la commande sed suivante permet d'y parvenir

cat file |  sed 's/from//g' | sed 's/to/    /g' | sed 's/+\w\+//' | \ 
sed 's/at//g' | sed 's/T/ /g' | sed 's/[[:digit:].]*\:$//' | \ 
sed 's/[[:digit:].]*\:$//' | sed 's/-$//' | sed 's/-$//' | sed 's/+$//'

et donne les résultats suivants

Received    2021-10-10 19:56:50
This is a message that contains words like  ,  , etc.

Sent        2021-10-11 06:50:57
This is another message that contains words like  ,  , etc.

Comme vous pouvez le voir, cela nettoie bien les lignes "Reçu" et "Envoyé". Mais il nettoie également les lignes de message ! Comment puis-je appliquer ces opérations uniquement aux lignes commençant par "Reçu" et "Envoyé" ?

2voto

mattb Points 262

Vous pouvez utiliser un modèle pour sélectionner les lignes auxquelles appliquer une commande ultérieure :

sed '/^Sent\|^Received/ s/pattern/replacement/' your_file

Bonus

Vous pouvez en fait effectuer toutes vos modifications en une seule commande sed :

sed '/^Received\|^Sent/ s/\(^[^ ]*\).*at \(.*\)T\(.*\)[-+].*/\1 \2 \3/' your_file

Essentiellement, le motif correspond à chaque morceau de texte de la ligne et nous nous contentons de mémoriser" tous les éléments que nous voulons conserver, puis nous remplaçons la ligne entière par ces éléments. par eux.

Sortie :

Received 2021-10-10 19:56:50
This is a message that contains words like from, at, etc.

Sent 2021-10-11 06:50:57
This is another message that contains words like to, at, etc.

Le fonctionnement est le suivant :

  • \( y \) sont des "groupes de capture" qui se souviennent de tout ce qui a été mis en correspondance dans les entre eux.
  • ^[^ ]* correspond au début d'une ligne suivie d'un nombre quelconque de consécutifs sans espace (c'est-à-dire le premier mot de la ligne).
  • .*at correspond à tout ce qui précède et inclut le mot "at" (et l'espace qui le suit) - il ne se trouve pas dans un groupe de capture et n'est donc pas "mémorisé".
  • \(.*\)T se souvient (dans le deuxième groupe de capture) de tout ce qui va jusqu'à, mais non compris la majuscule "T".
  • \(.*\)[-+].* se souvient (dans le troisième groupe de capture) de tout ce qui s'est passé jusqu'à, mais à un "-" ou un "+" (et tout ce qui suit le "-/+").
  • /\1 \2 \3/ signifie remplacer la correspondance (c'est-à-dire la ligne entière) par le contenu des 1ère, 2ème et 3ème lignes. contenu des 1er, 2e et 3e groupes de capture.

Cette page explique très bien sed - il dispose également d'un ensemble fantastique de autre unix tutoriels .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X