Je veux trouver des fichiers contenant deux chaînes ensemble, par exemple le fichier contient à la fois string1
et string2
.
Je veux le chemin complet des fichiers en sortie. Je ne veux pas voir les avertissements "autorisation refusée".
grep -l string2 `grep -l string1 /path/*`
ce qui est le même que
grep -l string2 $(grep -l string1 /path/*)
Edit: voici pourquoi grep string1 /path/* | grep string2
ne fait pas ce que je pense qu'alwbtc veut.
$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$
Rien trouvé, mais le fichier b contient les deux chaînes.
Voici ce que je pense que alwbtc veut
$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b
-l
option pour renvoyer les noms de fichiers au lieu des lignes. Il utilise ensuite le signe dollar ou les guillemets pour passer cette liste commeFILE
argument dans le deuxième grep. Cela permet au deuxième grep de rechercher l'intégralité de chaque fichier trouvé au lieu des lignes individuelles comme dans ma solution.-l
option pour que les deux commandes soient considérées comme égales.Connectez-vous les uns
grep
aux autres:grep "string1" /path/to/files/* | grep "string2"
la source
Voici la commande ack équivalente à la réponse de RedGrittyBrick :
Fonctionne de la même manière (sauf
ack
par défaut recherche récursivement le répertoire courant). Le contenu dans les$()
recherchesstring1
mais-l
ne génère que les noms de fichiers où cette chaîne a été trouvée. Ils sont ensuite passés en tant qu'arguments dans la commande externe, ce qui signifie que lastring2
recherche s'effectue uniquement dans cette liste de fichiers.la source
ou moins redondant:
Cela fonctionnera si les chaînes se trouvent sur des lignes différentes du même fichier et évitera également les faux positifs si un nom de fichier contient l'une des chaînes.
la source
Pour élaborer sur la solution de @ RedGrittyBrick qui présente un inconvénient lors de l'exécution de la commande sans assistance plus pour supprimer la sortie d'erreur comme prévu et pour rechercher des fichiers de manière récursive, vous pourriez envisager
grep -l 'STRING1' $(! grep -lrs 'STRING2' /absolute/path/to/search/dir && echo /dev/null)
-s
L'option supprimera les messages d'erreur L'-r
option permet de rechercher des chaînes dans des répertoires imbriqués arbitrairement!
combinés avec des&& echo /dev/null
garanties que la commande ne raccroche pas. Sinon, si leinner grep
ne trouve aucun fichier, il ne sortira rien, de sorte que l'outer grep
attendra indéfiniment pour la recherche. Cette solution de sorties/dev/null
dans ces cas afinouter grep
rechercherontSTRING1
dans/dev/null
où il est censé ne pas trouver quoi que ce soit.la source
Je cherchais un moyen extensible de faire 2 cordes ou plus et j'ai trouvé ceci:
Le premier grep trouve récursivement les noms des fichiers contenant
string1
dedanspath-to-files
.Les résultats sont canalisés dans
xargs
lesquels s'exécute une ou plusieurs commandes grep sur ces fichiers pourstring2
.Les résultats sont ensuite canalisés dans une autre
xargs
commande pourstring3
- c'est la même chose que le premierxargs
appel, mais en recherchant une chaîne différente.L'utilisation de
xargs
évitera les problèmes où il y a tellement de résultats que la ligne de commande résultante de l'utilisation des back-ticks est trop longue.Pour éviter les avertissements, nous pouvons rediriger
stderr
vers/dev/null
:Il n'est pas nécessaire lors des appels grep suivants, car il
string1
a déjà été trouvé dans le fichier, les autorisations sont donc réputées bonnes.la source