Comment puis-je grep un répertoire pour les lignes qui contiennent "Foo", mais obtenir uniquement des correspondances lorsque la ligne suivante contient également "Bar"?
grep
regular-expression
Nathan Long
la source
la source
Réponses:
@ warl0ck m'a pointé dans la bonne direction avec
pcregrep
, mais j'ai dit "contient", pas "est", et j'ai demandé un répertoire, pas un fichier.Cela semble fonctionner pour moi.
la source
Grep lui-même ne semble pas le supporter, utilisez plutôt pcregrep:
pcregrep -M "Foo\nBar" file
Eu:
la source
Foo
etBar
comprendrait toute la ligne.Avec un
sed
script:Pour l'utiliser :
L'
printf
afficher ici tous les fichiers du répertoire courant sur une ligne chaque, et le transmettre àsed
.Remarque : ceci est trié par ordre alphabétique.
Plus d'infos utiles
pattern space
ethold space
ICI .grymoire.com a de très bonnes choses sur la
shell
programmation.la source
h, n, H, x, p, q
signifie Très intéressant.pattern space
&hold space
: grymoire.com/Unix/Sed.html#uh-56 ou en français commentcamarche.net/faq/9536-sed-introduction-a-sed-part-iEn utilisant
grep
uniquement, vous pouvez construire le tuyau suivant:grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'
Le premier
grep
obtiendra toutes les lignes qui contiennentFoo
ainsi que la ligne après le match. Ensuite, nous obtenons des lignes qui contiennentBar
ainsi que la ligne avant la correspondance, et enfin extraire les lignes de cette sortie qui contiennentFoo
.EDIT: Comme l' a souligné Manatwork , il y a quelques cas problématiques à observer. Bien qu'il s'agisse d'un défi intéressant, en raison de
grep
la fonctionnalité orientée ligne, toute solution avec elle est susceptible d'être un «hack» et vous feriez probablement mieux d'utiliser quelque chose commepcregrep
ce qui est plus adapté à la tâche à accomplir.la source
find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
Bien que je préfère utiliser la solution de Nathan
pcregrep
, voici une solution utilisant uniquement grepExplication des options:
-o
imprimer uniquement la partie assortie. Nécessaire car l'inclusion de-z
va imprimer tout le fichier (sauf s'il y a un \ 0 quelque part)-z
Traitez l'entrée comme un ensemble de lignes, chacune se terminant par un octet zéro (le caractère ASCII NUL) au lieu d'une nouvelle ligne.-P
syntaxe de regex perlEDIT: Cette version imprime des lignes appariées entières
la source
-z
. Quelques «(. *)» Avant et après l'expression entière lui feraient sortir toutes les lignes correspondantes. Pour l'instant, les sous-chaînes avant "Foo" et après "Bar" ne sont pas affichées.Avec awk:
(remarque générale sur la limitation de awk: attention, si certains noms de fichiers peuvent contenir des caractères "=", vous devrez les passer comme
./filename
au lieu defilename
awk)la source