Je fais un find
puis j'obtiens une liste de fichiers. Comment puis-je le diriger vers un autre utilitaire comme cat
(de sorte que cat affiche le contenu de tous ces fichiers) et avoir essentiellement besoin de grep
quelque chose de ces fichiers.
Tuyauterie vers un autre processus (bien que cela n'accomplisse pas ce que vous avez dit que vous essayez de faire):
command1 | command2
Cela enverra la sortie de command1 comme entrée de command2
-exec
sur un find
(cela fera ce que vous voulez faire - mais est spécifique à find
)
find . -name '*.foo' -exec cat {} \;
(Tout ce qui se trouve entre find
et -exec
sont les prédicats de recherche que vous utilisiez déjà. {}
Remplacera le fichier particulier que vous avez trouvé dans la commande ( cat {}
dans ce cas); \;
c'est pour terminer la -exec
commande.)
envoyer la sortie d'un processus en tant qu'arguments de ligne de commande à un autre processus
command2 `command1`
par exemple:
cat `find . -name '*.foo' -print`
(Notez que ce ne sont pas des guillemets réguliers (sous le tilde ~ de mon clavier).) Cela enverra la sortie de command1
dans en command2
tant qu'arguments de ligne de commande. Notez que les noms de fichiers contenant des espaces (sauts de ligne, etc.) seront cependant divisés en arguments séparés.
find -name '*.foo' -print
a très bien fonctionné pour moi ... Mercifind
vous permettent d'écrire:,find . -name '*.foo' -exec cat {} +
où le+
indique quefind
doit regrouper autant de noms de fichiers que possible en une seule invocation de commande. Ceci est très utile (il traite des espaces, etc. dans les noms de fichiers sans recourir à-print0
etxargs -0
).find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
Version moderne
POSIX 2008 a ajouté le
+
marqueur,find
ce qui signifie qu'il regroupe désormais automatiquement autant de fichiers qu'il est raisonnable en une seule exécution de commande, tout comme lexargs
fait, mais avec un certain nombre d'avantages:Le problème du nom de fichier est un problème avec
xargs
sans l'-0
option, et le problème "exécuter même avec zéro nom de fichier" est un problème avec ou sans l'-0
option - mais GNUxargs
a l' option-r
ou--no-run-if-empty
pour empêcher que cela ne se produise. En outre, cette notation réduit le nombre de processus, pas que vous êtes susceptible de mesurer la différence de performances. Par conséquent, vous pourriez raisonnablement écrire:Version classique
Si vous êtes sous Linux ou avez le GNU
find
et lesxargs
commandes, utilisez-print0
avecfind
et-0
avecxargs
pour gérer les noms de fichiers contenant des espaces et d'autres caractères impairs.Ajuster les résultats de
grep
Si vous ne voulez pas les noms de fichiers (juste le texte), ajoutez une option appropriée à
grep
(généralement-h
pour supprimer les «en-têtes»). Pour garantir absolument que le nom de fichier est imprimé pargrep
(même si un seul fichier est trouvé ou si la dernière invocation degrep
n'est donnée que 1 nom de fichier), puis ajoutez/dev/null
à laxargs
ligne de commande, de sorte qu'il y aura toujours au moins deux noms de fichiers.la source
xargs grep something
.find
est dirigée vers l'entrée standard dexargs
. Lexargs
programme lit son entrée standard, divise l'entrée à un espace blanc (blancs, sauts de ligne, tabulations, etc.) et ajoute un certain nombre de mots à la commandegrep something
et exécute la ligne de commande.xargs
continue ensuite à lire les entrées et à exécuter les commandes jusqu'à ce qu'elles soient épuisées.xargs
exécute lagrep
commande aussi souvent que nécessaire pour l'entrée qui lui est donnée (à partir defind
dans cet exemple)./dev/null
perd les messages d'erreur.Il existe plusieurs façons de transmettre la liste des fichiers renvoyés par la
find
commande à lacat
commande, bien que techniquement tous n'utilisent pas de tuyauterie et qu'aucun ne soit directement dirigé verscat
.Le plus simple est d'utiliser des backticks (
`
):Cela prend la sortie de
find
et la place effectivement sur la ligne de commande decat
. Cela ne fonctionne pas bien s'ilfind
a trop de sortie (plus que ce qui peut tenir sur une ligne de commande) ou si la sortie a des caractères spéciaux (comme des espaces).Dans certains shells, notamment
bash
, on peut utiliser à la$()
place des backticks:C'est moins portable, mais est emboîtable. Mis à part cela, il a à peu près les mêmes mises en garde que les contre-coups.
Parce que l'exécution d'autres commandes sur ce qui a été trouvé est une utilisation courante pour
find
, find a une-exec
action qui exécute une commande pour chaque fichier qu'il trouve:Le
{}
est un espace réservé pour le nom de fichier, et les\;
marques de la fin de la commande (il est possible d'avoir d' autres actions après-exec
.)Cela s'exécutera
cat
une fois pour chaque fichier plutôt que d'exécuter une seule instance en luicat
passant plusieurs noms de fichiers, ce qui peut être inefficace et ne pas avoir le comportement que vous souhaitez pour certaines commandes (bien que ce soit bien pourcat
). La syntaxe est également difficile à taper - vous devez échapper au point-virgule car le point-virgule est spécial pour le shell!Certaines versions de
find
(notamment la version GNU) vous permettent de remplacer;
par+
pour utiliser-exec
le mode d'ajout pour exécuter moins d'instances decat
:Cela passera plusieurs noms de fichiers à chaque invocation de
cat
, ce qui peut être plus efficace.Notez cependant qu'il n'est pas garanti d'utiliser une seule invocation. Si la ligne de commande est trop longue, les arguments sont répartis sur plusieurs invocations de
cat
. Carcat
ce n'est probablement pas un gros problème, mais pour certaines autres commandes, cela peut changer le comportement de manière indésirable. Sur les systèmes Linux, la limite de longueur de ligne de commande est assez grande, donc la division en plusieurs invocations est assez rare par rapport à certains autres systèmes d'exploitation.L'approche classique / portable consiste à utiliser
xargs
:xargs
exécute la commande spécifiée (cat
, dans ce cas) et ajoute des arguments en fonction de ce qu'elle lit depuis stdin. Tout comme-exec
avec+
, cela interrompra la ligne de commande si nécessaire. Autrement dit, sifind
produit trop de sortie, il s'exécuteracat
plusieurs fois. Comme mentionné dans la section-exec
précédente, il existe certaines commandes où cette séparation peut entraîner un comportement différent. Notez que l'utilisation dexargs
ce type a des problèmes avec les espaces dans les noms de fichiers, carxargs
utilise simplement des espaces comme délimiteur.La méthode la plus robuste, portable et efficace utilise également
xargs
:L'
-print0
indicateur indiquefind
d'utiliser des\0
délimiteurs (caractère nul) entre les noms de fichiers, et l'-0
indicateur indiquexargs
d'attendre ces\0
délimiteurs. Cela a un comportement à peu près identique à l' approche-exec
...+
, bien qu'il soit plus portable (mais malheureusement plus verbeux).la source
ls
.$()
également avec des commandes autres quefind
.Pour ce faire (en utilisant bash), je ferais ce qui suit:
Ceci est connu comme la "substitution de commande" et il supprime le saut de ligne par défaut, ce qui est vraiment pratique!
plus d'infos ici
la source
Cela me semble être un travail pour un script shell:
ou quelque chose comme ça
la source
Voici ma façon de trouver des noms de fichiers qui contiennent du contenu qui m'intéresse, juste une seule ligne bash qui gère également les espaces dans les noms de fichiers:
la source
J'utilise quelque chose comme ça:
L'
-print0
argument " " pour "trouver" et "-0
" l'argument pour "xargs" sont nécessaires pour gérer correctement les espaces dans les chemins / noms de fichiers.la source
La commande find a un argument -exec que vous pouvez utiliser pour des choses comme ça, vous pouvez simplement faire le grep directement en utilisant cela.
Par exemple (à partir d'ici, d'autres bons exemples sur cette page ):
la source
Voici ma photo à usage général:
Il imprimera le nom du fichier
la source
En bash, les éléments suivants seraient appropriés:
Cela trouvera tous les fichiers dans le
/dir
répertoire etxargs
dirigera les noms de fichiers en toute sécurité, qui conduiront en toute sécuritégrep
.Ignorer
xargs
n'est pas une bonne idée si vous avez plusieurs milliers de fichiers dans/dir
;cat
se cassera en raison de la longueur excessive de la liste des arguments.xargs
va tout régler pour vous.L'
-print0
argument àfind
mailles avec l'-0
argument àxargs
pour gérer correctement les noms de fichiers avec des espaces. L'-i
argument àxargs
vous permet d'insérer le nom de fichier à l'endroit requis dans lacat
ligne de commande. Les crochets sont remplacés par le nom de fichier redirigé vers lacat
commande à partir defind
.la source
Ça marche pour moi
la source
Utilisez ggrep .
rechercher un fichier sous unix contenant du texte situé dans le répertoire courant ou un sous-répertoire
la source
Cela affichera le nom et le contenu des fichiers de manière récursive uniquement.
Modifier (version améliorée): Cela imprime le nom et le contenu des fichiers texte (ascii) de manière récursive uniquement.
Encore une tentative
la source
Essayez-vous de trouver du texte dans des fichiers? Vous pouvez simplement utiliser grep pour cela ...
la source
Pour lister et voir le contenu de tous les fichiers abc.def sur un serveur dans les répertoires / ghi et / jkl
Pour lister les fichiers abc.def qui ont commenté des entrées et les afficher, voyez ces entrées dans les répertoires / ghi et / jkl
la source