Problème avec grep successifs

Bonjour,

pour lister les fichiers contiennant le mot “pomme”, j’utilise la commande grep :

grep -il “pomme” ./*

Du coup, le résultat est :

./a.html
./b.html
./c.html
./d.html
./e.html
./f.html

maintenant j’ai encore besoin de faire un grep sur ce resultat pour trouver les fichiers contenant le mot “fraise”, pour cela, je pense que je doit utiliser la pipe “|”.

Mais comment faire ?

Merci d’avance pour vos réponses.

Ce n’est pas un pipe qu’il faut faire, mais utiliser la sortie du premier grep comme argument du second :

grep -il "fraise" $(grep -il "pomme" ./*)

Attention à la limite de longueur d’une ligne de shell si le nombre de fichiers est important.
Il y a probablement une méthode plus propre pour faire cela, mais le shell n’est pas ma spécialité.

1 J'aime

Merci PascalHambourg, ça marche.

Du coup, si je veux appliquer un grep une 3ème fois pour trouver les fichiers qui contiennent le nom “cassis” parmi ceux trouvés du 2ème grep,

est-ce que cette syntaxe est bonne ?

grep -il "cassis" $(grep -il "fraise" $(grep -il "pomme" ./*))

Je pense que oui, mais la syntaxe commence à devenir lourde, c’est pourquoi j’ai écrit qu’il doit y avoir une meilleure méthode.

1 J'aime

Merci à toi

Bonjour

C’est hors sujet car il ne s’agit pas de grep
mais la solution que je propose n’utilise qu’une seule commande : awk ( ou gawk ou mawk )

gawk 'FNR==1 {pom=fra=cas=0}
/pomme/  {pom=1}
/fraise/ {fra=1}
/cassis/ {cas=1}
pom && fra && cas {print FILENAME; nextfile}' *.txt 

qu’on peut aussi écrire sur une seule ligne :

gawk 'FNR==1{pom=fra=cas=0};/pomme/{pom=1};/fraise/{fra=1};/cassis/{cas=1};pom&&fra&&cas{print FILENAME;nextfile}' *.txt


NOTE : sur mon système debian,

/usr/bin/awk est un lien symbolique vers /etc/alternatives/awk
et
/etc/alternatives/awk est un lien symbolique vers le programme /usr/bin/gawk

En d’autres termes, sur mon système awk <=> gawk

Donc ces lignes de commande fonctionnent
aussi bien en utilisant le lien awk
qu’en utilisant la commande gawk
et je viens de vérifier aussi que ça fonctionne avec mawk

1 J'aime

La syntaxe devient lourde, c’est le signe que la solution initiale à base de l’opérateur pipeè|` était la bonne:

fgrep -i pomme ./* | fgrep -i fraise | fgrep -i cassis

Ici le critère est de trouver les lignes contenant à la fois “pomme” “fraise” et “cassis”. C’est un et logique.

Si on veut les lignes qui contiennent soit “pomme”, soit “fraise” soit “cassis”, c’est un ou logique et dans ce cas le plus simple est d’utiliser les propriétés des expressions rationnelles regex

egrep -i 'pomme|fraise|cassis' ./*
̀```

Cordialement,
Regards,
Mit freundlichen Grüßen,
مع  تحياتي الخالصة  
---
F. Petitjean
Ingénieur civil du Génie Maritime.

« Celui qui, parti de rien, n'est arrivé nulle part n'a de merci à dire à personne !! »
       Pierre Dac

fluo veut les noms des fichiers .

fluo veut les noms des fichiers qui contiennent “pomme” ET “fraise”.