Commande Unix à la Liste des fichiers contenant la chaîne de mais *PAS* contenant une autre chaîne
Comment puis-je récursivement afficher une liste de fichiers qui a une chaîne de caractères et plus précisément de ne pas disposer d'une autre chaîne? Aussi, je veux dire à évaluer le texte les fichiers, pas les noms de fichiers.
Conclusion:
Que par les commentaires, j'ai fini par utiliser:
find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'
Cette retourné fichiers avec "cartes de base" et non pas "cartes de base-bot". Merci!!!!!
- La plus simple façon est d'utiliser
grep -l
à la liste des fichiers correspondant à un modèle, puis de la pipe que pourgrep -v
. - Appartient sur superuser.com
- Mikel: Cependant, il va de la pipe seulement les noms de fichier à l'autre
grep
qui à son tour peut filtrer uniquement à partir de ces noms de fichier et non pas le contenu du fichier. - J'ai essayé, et d'accord avec Alan qu'il ne les filtres de fichiers. Ainsi, il n'est pas accomplir ce que j'espère.
- Ne pouvez pas vous passer grep un fileset, et si oui, pouvez pas vous passer une fileset basé sur un autre grep? C'est juste moi d'imaginer les possibilités, mais si quelqu'un savait comment faire, ce serait génial 😀
- Matrym: quelque Chose de semblable à
ls -1 *.html | xargs grep -l '<foo>' - | xargs grep -L '<bar>' -
peut être fait, comme il a été indiqué par Ponceuse Marechal.
Vous devez vous connecter pour publier un commentaire.
Essayez ceci:
Explication:
grep -lr
fait grep de manière récursive (r) sortie une liste (l) de tous les fichiers qui contiennent<string-to-match>
. xargs boucles sur ces fichiers, appelantgrep -L
sur chacun d'eux.grep -L
n'affichera que le nom de fichier lorsque le fichier ne contient pas de<string-not-to-match>
.-R
avecfind
comme c'est déjà récursive. Utilisez uniquement-R
sigrep
est utilisé par lui-même.L'utilisation de xargs dans les réponses ci-dessus n'est pas nécessaire; vous pouvez obtenir la même chose comme ceci:
grep -q
signifie exécuter tranquillement mais retourne un code de sortie indiquant si une correspondance a été trouvée;find
pouvez ensuite utiliser ce code de sortie pour déterminer s'il convient de conserver à exécuter le reste de ses options. Si-exec grep -q <string-to-match> {} \;
renvoie la valeur 0, alors il va continuer à exécuter-not -exec grep -q <string-not-to-match>{} \;
. Si cela renvoie 0, il va continuer à exécuter-print
, qui imprime le nom du fichier.Comme une autre réponse a noté, en utilisant
find
de cette façon, a de grands avantages par rapportgrep -Rl
où vous voulez seulement de rechercher les fichiers d'un certain type. Si, d'autre part, vous voulez vraiment à la recherche de tous les fichiers,grep -Rl
est probablement plus rapidement, car il utilise unegrep
processus pour effectuer le premier filtre pour tous les fichiers, au lieu de se séparergrep
processus pour chaque fichier.Ces réponses semblent à mesure que le match les DEUX cordes. La commande suivante devrait mieux fonctionner:
Ici est un générique de construction:
Cette commande génère les fichiers dont le nom correspond à
<nameFilter>
(ajusterfind
prédicats que vous en avez besoin) qui contiennent<patternYes>
, mais ne contiennent pas de<patternNo>
.Les améliorations sont:
Si vous n'avez pas besoin de filtre par nom (souvent, on veut tenir compte de tous les fichiers dans le répertoire courant), vous pouvez la bande
find
et ajouter-R
pour la premièregrep
:trouver . -maxdepth 1 -name "*.py" -exec grep -L "chaîne-pas-de-match" {} \;
Cette Commande permettra d'obtenir toutes ".py" des fichiers qui ne contiennent pas de "chaîne-pas-de-match" au même répertoire.