J'essaie de trouver tous les fichiers qui sont d'un certain type et ne contiennent pas une certaine chaîne. J'essaye de m'y prendre en cherchant à grep -v
exemple:
find -type f -name '*.java' | xargs grep -v "something something"
Ça n'a pas l'air de fonctionner. Il semble simplement renvoyer tous les fichiers trouvés par la commande find. Ce que j'essaie de faire est de trouver fondamentalement tous les fichiers .java qui correspondent à un certain nom de fichier (par exemple, se terminent par «Pb» comme dans SessionPb.java) et qui n'ont pas de «étend quelque chose» à l'intérieur.
Je soupçonne que je me trompe. Alors, à quoi devrait ressembler la commande à la place?
Réponses:
Il n'y a aucun besoin
xargs
ici. Vous devez également utilisergrep
avec l'-L
option (fichiers sans correspondance), provoquer sinon il affichera le contenu du fichier au lieu de son nom, comme dans votre exemple.la source
-L
a déjà la négociation, car cela signifiefiles _without_ match
. Par conséquent, vous n'avez pas besoin d'-v
option ici.find -exec \+
quelqu'un m'écrit qu'il vaut mieux utiliser xargs. pourquoi personne ne regarde l'homme avant d'écrire un commentaire? (:-exec ... {} \+
n'est pas équivalent àxargs
. Veuillez lire la documentation de findutils! (J'ai travaillé assez dur dessus!)xargs
traite son entrée et sépare les arguments sur l'espace blanc. Les devis sont également spéciaux (par défaut) pourxargs
. Aucune de ces choses n'est vraie-exec ... {} +
. Les anciennes versions dexargs
considéraient le trait de soulignement comme un indicateur EOF, mais ce n'est plus le cas.Vous l'avez presque vraiment ...
Le point '.' dit de commencer à partir d'ici. (le vôtre implique .. mais ne présumez jamais).
-iname utilise la recherche insensible à la casse, juste au cas où (ou juste en aucun cas).
-print0 envoie les noms de fichiers à xargs avec un caractère \ x00 de fin, ce qui évite les problèmes avec les noms de fichiers contenant des espaces.
le '-0' sur xargs indique qu'il faut s'attendre à des noms de fichiers se terminant par \ x00 au lieu de retours.
et votre commande grep ...
J'ai presque compris.
ÉDITER::
Depuis votre mise à jour:
devrait aider. (Ajouté -L de la réponse de @ rush, bon travail)
J'ai l'idée que votre grep a besoin de l'option '-i' ou d'être moins explicite.
Essayez la commande en plusieurs parties ... CE nom de fichier de sortie semble-t-il correct?
Si c'est le cas, votre problème est probablement soit votre modèle de recherche grep ne correspond pas (erreur d'orthographe? Ça arrive!), Soit il n'y a tout simplement pas de correspondance.
Pire cas absolu:
fera BEAUCOUP plus de travail pour tout rechercher, mais devrait vous donner une sortie.
la source
xargs -0 grep -v "something something"
devrait êtrexargs -0 grep -v "something something" /dev/null
autrement, vous obtiendrez des résultats étranges lorsque find ne produit aucun fichier correspondant.L'ordinateur est un ordinateur: il fait ce que vous lui avez dit au lieu de ce que vous vouliez qu'il fasse.
grep -v "something something"
imprime toutes les lignes qui ne contiennent passomething something
. Par exemple, il imprime deux lignes parmi les trois suivantes:Pour imprimer des fichiers qui ne contiennent
extends SomethingSomething
nulle part, utilisez l'-L
option:Certaines versions de grep n'ont pas cette
-L
option (elle n'est pas spécifiée par POSIX ). Si le vôtre ne le fait pas, ne l'imprimez rien et utilisez le code de retour pour que le shell appelant fasse ce qu'il devrait faire à la place.Vous pouvez également utiliser awk.
Sur Linux ou Cygwin (ou tout autre système avec GNU grep), vous n'avez pas besoin d'utiliser
find
, car ilgrep
est capable de se reproduire.Si votre shell est ksh ou bash ou zsh, vous pouvez faire en sorte que le shell fasse correspondre le nom de fichier. Sur bash, lancez d'
set -o globstar
abord (vous pouvez le mettre dans votre~/.bashrc
).la source
\s
est une extension GNU grep, avec laquelle je pense est synonyme[[:space:]]
.