Peut effectuer une recherche uniquement dans les fichiers correspondant à un modèle 'glob' spécifique (par exemple, recherchez foo dans tous les fichiers nommés "bar * .c"). La commande
ack foo "bar*.c"
ne fonctionne que dans le répertoire en cours.
Note: Je sais que c'est possible avec find -exec:
find . -name "bar*.c" -type f -exec ack foo {} +
Mais je voudrais une petite et simple commande ack, car find ne saute pas les répertoires de contrôle de version.
find . -name "bar*.c" -exec ack foo {} \;
? Il n'y a rien de spécialgrep
, vous pouvez utiliser n'importe quelle commande avec find-exec
.Réponses:
Recherche dans les annuaires
D'après le synopsis présenté dans la page de manuel, je dirais que oui, il peut traiter un répertoire, mais en regardant les commutateurs, il ne peut pas rechercher uniquement un fichier basé sur un modèle. Pour cela, vous devrez vous enrôler
find
. La commandeack
inclut l'option--files-from=FILE
afin qu'elle puisse être alimentée avec une liste de fichiersfind
.synopsis
usage
Il y a l'
--ignore-file=
option qui peut vous donner ce que vous voulez mais semble un peu pénible à utiliser.Recherche de types de fichiers spécifiques
La seule autre façon que je puisse concevoir de faire cela via
ack
consiste à utiliser son--type
commutateur:Pour voir quels types sont disponibles:
format. Par exemple, les deux types --type = perl et --perl fonctionnent. - [no] cpp .cpp .cc .cxx .m .hpp .hh .h .hxx - [no] objcpp .mm .h - [no] perl .pl .pm .pod .t .psgi; correspond à la première ligne /^#!.*\bperl/ - [no] perltest .t
Exemples
Trouvez tous les fichiers Perl, en fonction du nom de fichier (* .pm, * .pl, * .t et * .pod) et de la ligne shebang.
Trouvez tous les fichiers C ++:
Recherche de foo in bar * .c
Alors, comment pouvez-vous accomplir ce que vous voulez? Eh bien, vous devrez probablement utiliser
find
pour faire ceci:Vous pouvez également utiliser
ack
la possibilité de rechercher des fichiers qui correspondent à un modèle donné dans leurs noms de fichier (using-g <pattern>
), puis de passer cette liste à un second appel deack
using-x
ou--files-from=-
..Utilisant
-x
:Utilisant
-files-from=-
:Dans les deux cas, nous faisons correspondre les noms de fichiers que vous souhaitez utiliser avec cette expression rationnelle:
Cela correspond à des fichiers dont le nom est
bar.*c
et de fin après l'.c
utilisation de la fin de l' ancrage de la ligne,$
. Nous vérifions également que les noms ont un caractère de limite\b
. Cela échouera pour les fichiers contenant des caractères de limite tels que$bar.c
ou%bar.c
par exemple.la source
cpp
fichiersack --type=cpp <string>
. Voirack
la page de manuel de pour plus sur tout cela cependant. Mais ce que je vous dis fondamentalement, c'est que vous ne pouvez pas utiliserack
la méthode que vous souhaitez.ack
ne peut pas faire ce qui a été demandé.find adir -iname "bar*.c" | ack --files-from=- foo
. Ou, si vous voulez juste un fichier:echo "barBaz.c" | ack --files-from=- foo
ack -g '\bbar.*.c$' | ack -x foo
C'est facile si le type de fichier est connu et ack connaît beaucoup de types de fichiers. Donc, si, par exemple, vous voulez chercher uniquement dans les fichiers C, vous pouvez le faire:
Mais si ce n'est pas une des extensions connues, vous devez définir votre propre type. Cela devrait fonctionner:
Notez que vous avez besoin des deux types --type-set et --barc.
(Merci à Andy, qui a également contribué à cela sur la liste de diffusion.)
la source
man ack
n'aide pas vraiment et n'a pascc
quand je cherche ça."Quoi de neuf dans ack 2?" http://beyondgrep.com/ack-2.0/
Seulement je ne peux pas le faire fonctionner:
Ainsi, il semble que -g ait besoin d'une expression régulière, alors que je veux une option de style 'glob' ...
la source
-g
prend une regex, pas un glob. Vous pouvez écrire votre regex comme.*bar.*\.c$
.Cela semblerait être le plus rapide et le plus sûr:
-x Lire la liste des fichiers à rechercher à partir de STDIN.
Toutefois, si le fichier est susceptible de figurer dans votre
locate
base de données, cela serait encore plus rapide:Locate peut également accepter les expressions régulières old-school, un peu pénibles, mais si vous recherchez des
c
fichiers, cela peut être nécessaire. par exempleCela se traduit simplement par "recherche dans tous les noms de fichiers se terminant par c, cpp, h, hpp ou cc".
la source
Ack ne prend pas en charge la sélection de fichiers de style glob. Depuis que cela me manque vraiment, j'ai créé un petit script shell ackg :
Maintenant, vous pouvez utiliser la commande:
Mais attention: ceci cherchera malheureusement aussi dans les répertoires de contrôle de version (par exemple: .git).
la source
Cela peut être fait avec l'
-G
option to ag, le chercheur d'argent (un clone amélioré de ack-grep).Remarques:
ag
utilise la syntaxe d'expression régulière PCRE , donc l'expression rationnelle doit être à labar.*\.c
place debar*.c
.-G
option doit précéder le terme recherché, car tout ce qui suit est interprété comme un nom de fichier.la source
Voulez-vous seulement un certain motif ou voulez-vous simplement des fichiers source C?
Si vous voulez tous les fichiers C, utilisez
Si vous voulez que tous les fichiers C et les fichiers d’en-tête NOT C, utilisez
la source
La réponse de @chim est la meilleure, mais elle est écrite sous forme de commentaire, alors je la republie sous forme de réponse officielle ...
J'aime le fait que tu puisses regex le chemin ...
la source
En utilisant zsh, vous pouvez faire:
la source
ls
.