Je voudrais simplement passer cela une seconde grep
pour les supprimer:
grep -r --exclude={\*~,\*.map} "OK" bar/ | grep -vP '(?<!debug)\.js'
L' -v
inverse la correspondance, l'impression de lignes qui ne correspondent pas au motif et -P
permet les expressions régulières compatibles Perl qui nous permettent d'utiliser des lookbhinds négatifs . Cette expression régulière particulière correspondra à ce .js
qui n'est pas précédé par debug
quel moyen (puisque nous inversons les correspondances) que seuls ces .js
fichiers seront imprimés.
Cependant, comme l'a souligné @QuestionOverflow dans les commentaires, cela pourrait avoir pour effet secondaire inattendu de filtrer les lignes qui contiennent OK
et js
puisque le grep -v
est appliqué à la sortie entière, pas seulement le nom du fichier. Pour éviter cela, ajoutez simplement deux points (c'est ce qui permet grep
de séparer les noms de fichier du contenu du fichier):
grep -r --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js:'
Cela échouera toujours si votre ligne d'entrée contient foo.js:
ou si votre nom de fichier contient :
. Donc, pour être sûr, utilisez une approche différente:
grep -Tr --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js\t'
Les -T
causes grep
pour imprimer un onglet entre le nom de fichier et le contenu du fichier. Donc, si nous ajoutons simplement un \t
à la fin de l'expression régulière, il ne correspondra qu'aux noms de fichiers et non au contenu de la ligne.
Néanmoins, l' utilisationfind
pourrait avoir plus de sens malgré tout.
OK
et.js
sur la même ligne?find
c'est probablement mieux pour ce genre de chose. Obtenir le bongrep
peut être délicat comme vous l'avez souligné :).failglob
options est définie dans le shell:bash: no match: --exclude=*~
vous devez citer vos arguments de modèle GLOB--exclude
pour les cacher de l'expansion du shell, par exemple--exclude={\*~,\*.map}
J'utiliserais
find
pour localiser les fichiers et diriger le résultat viaxargs
:Ceci recherche chaque fichier ne correspondant pas à "
*~
", "*.map
" ou "*.js
mais pas*.debug.js
".En utilisant
find
vous pouvez facilement rechercher des règles plutôt complexes et cette approche vous évite de supprimer accidentellement les faux positifs comme cela pourrait arriver avec le doublegrep
.la source
-exec grep OK {} +
au lieu dexargs
et éviter un programme supplémentaire.-exec +
non-exec \;
, cela exécutera le moins de commandes possible, un peu commexargs
.Avec
zsh
vous pouvez faire:À condition bien sûr que la liste des arguments ne soit pas trop longue, auquel cas vous pouvez toujours faire:
la source
zsh
autoload zargs
zargs some/dir/**/^(*~|*.map|(^*debug).js) -- grep OK
Si cela ne vous dérange pas de voir la sortie légèrement hors service (si vous le faites, vous pouvez la trier):
Cela nécessite que votre shell prenne en charge la globalisation
**
récursive: zsh estshopt -s globstar
prêt à l'emploi , bash le fait après l'exécution , ksh93 le fait après l'exécutionset -o globstar
.Sans
**
prise en charge dans le shell, vous pouvez utiliser deux commandes grep:la source
**
, mais il semble y avoir quelque chose de mal avec l'argument supplémentaire**/*.debug.js
, provoquant l'interprétation de grepOK
comme un répertoire. Avez-vous essayé de l'exécuter?Vous pouvez utiliser
ripgrep
. Par défaut, il ignore les fichiers cachés et respecte votre.gitignore
fichier.Vous pouvez spécifier les règles d'inclusion ou d'exclusion à l'aide des paramètres suivants:
Voici quelques exemples simples:
Voici la solution complète pour exclure
*.~
,*.map
,*.js
mais non*.debug.js
:Essai:
la source