Voici le texte du fichier:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
J'ai besoin de grep pour "42B" et d'obtenir la sortie du texte ci-dessus comme:
Pseudo name=Apple
Code=42B
state=fault
Quelqu'un a-t-il une idée sur la façon d'y parvenir en utilisant grep
/ awk
/ sed
?
Réponses:
Avec
awk
RS=
change le séparateur d'enregistrement d'entrée d'une nouvelle ligne en lignes vides. Si un champ d'un enregistrement contient/42B/
imprimer l'enregistrement.''
(la chaîne nulle) est une valeur magique utilisée pour représenter les lignes vides selon POSIX :Les paragraphes de sortie ne seront pas séparés car le séparateur de sortie reste une seule nouvelle ligne. Pour vous assurer qu'il y a une ligne vide entre les paragraphes de sortie, définissez le séparateur d'enregistrement de sortie sur deux retours à la ligne:
la source
FILENAME
), ce n'est pas une mauvaise idée d'utiliser la redirection car cela évite les problèmes de nom de fichier contenant=
ou commençant par-
(ou étant-
), crée des messages d'erreur cohérents et évite d'exécuterawk
ou d'exécuter d'autres redirections si le fichier d'entrée ne peut pas être ouvert.En supposant que les données sont structurées de sorte que ce soit toujours la ligne avant et après que vous voulez, vous pouvez utiliser les commutateurs de grep
-A
(après) et-B
(avant) pour lui dire d'inclure la 1 ligne avant la correspondance et 1 ligne après:Si vous voulez les mêmes lignes numériques avant et après le terme de recherche, vous pouvez utiliser le
-C
commutateur (context):Si vous souhaitez être plus rigoureux lors de la correspondance des plusieurs lignes, vous pouvez utiliser l'outil
pcregrep
, pour faire correspondre un modèle sur plusieurs lignes:Le modèle ci-dessus correspond comme suit:
-M
- plusieurs lignes'Pseudo.*\n.*42B.*\nstate.*'
- correspond à un groupe de chaînes où la première chaîne commence par le mot"Pseudo"
suivi de tout caractère jusqu'à la fin de la ligne\n
, suivi de tout caractère jusqu'à la chaîne"42B"
suivi de tout caractère jusqu'à une autre fin de ligne (\n
), suivi de la chaîne"state"
suivi de tous les caractères.la source
-C
(contexte) peut être utilisé comme raccourci, si-A
et-B
sont les mêmes.Il existe probablement un moyen similaire de le faire avec awk, mais en perl:
Cela dit essentiellement de diviser le fichier en morceaux délimités par des lignes vides, puis d'imprimer uniquement les morceaux qui correspondent à votre expression régulière.
la source
cat
;perl -00 -ne 'print if /42B/' file
La
grep
de quelques saveurs d'Unix ont le-p
drapeau pour « paragraphe ». Je sais qu'AIX le fait .ferait exactement ce que vous demandez là-bas. YMMV et GNU grep n'ont pas cet indicateur.
la source
Une autre solution Perl, sans ligne vide de fin:
Exemple
la source
perl -00 -ne 'print if /42B/' file
.