Je fais un findpuis 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 grepquelque chose de ces fichiers.
Je fais un findpuis 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 grepquelque chose de ces fichiers.
Réponses:
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
-execsur 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 findet -execsont 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 -execcommande.)
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 command1dans en command2tant 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.
findvous permettent d'écrire:, find . -name '*.foo' -exec cat {} +où le +indique que finddoit 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 à -print0et xargs -0).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 a ajouté le +marqueur, findce qui signifie qu'il regroupe désormais automatiquement autant de fichiers qu'il est raisonnable en une seule exécution de commande, tout comme le xargsfait, mais avec un certain nombre d'avantages:
Le problème du nom de fichier est un problème avec xargssans l' -0option, et le problème "exécuter même avec zéro nom de fichier" est un problème avec ou sans l' -0option - mais GNU xargsa l' option -rou --no-run-if-emptypour 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:
find . -exec grep something {} +
find . -print | xargs grep something
Si vous êtes sous Linux ou avez le GNU findet les xargscommandes, utilisez -print0avec findet -0avec xargspour gérer les noms de fichiers contenant des espaces et d'autres caractères impairs.
find . -print0 | xargs -0 grep something
grepSi vous ne voulez pas les noms de fichiers (juste le texte), ajoutez une option appropriée à grep(généralement -hpour supprimer les «en-têtes»). Pour garantir absolument que le nom de fichier est imprimé par grep(même si un seul fichier est trouvé ou si la dernière invocation de grepn'est donnée que 1 nom de fichier), puis ajoutez /dev/nullà la xargsligne de commande, de sorte qu'il y aura toujours au moins deux noms de fichiers.
xargs grep something.
findest dirigée vers l'entrée standard de xargs. Le xargsprogramme 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 commande grep somethinget exécute la ligne de commande. xargscontinue ensuite à lire les entrées et à exécuter les commandes jusqu'à ce qu'elles soient épuisées. xargsexécute la grepcommande aussi souvent que nécessaire pour l'entrée qui lui est donnée (à partir de finddans cet exemple).
/dev/nullperd les messages d'erreur.
Il existe plusieurs façons de transmettre la liste des fichiers renvoyés par la findcommande à la catcommande, bien que techniquement tous n'utilisent pas de tuyauterie et qu'aucun ne soit directement dirigé vers cat.
Le plus simple est d'utiliser des backticks ( `):
cat `find [whatever]`
Cela prend la sortie de findet la place effectivement sur la ligne de commande de cat. Cela ne fonctionne pas bien s'il finda 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:
cat $(find [whatever])
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 -execaction qui exécute une commande pour chaque fichier qu'il trouve:
find [whatever] -exec cat {} \;
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 catune fois pour chaque fichier plutôt que d'exécuter une seule instance en lui catpassant 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 pour cat). 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 -execle mode d'ajout pour exécuter moins d'instances de cat:
find [whatever] -exec cat {} +
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. Car catce 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:
find [whatever] | xargs cat
xargsexé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 -execavec +, cela interrompra la ligne de commande si nécessaire. Autrement dit, si findproduit trop de sortie, il s'exécutera catplusieurs fois. Comme mentionné dans la section -execprécédente, il existe certaines commandes où cette séparation peut entraîner un comportement différent. Notez que l'utilisation de xargsce type a des problèmes avec les espaces dans les noms de fichiers, car xargsutilise simplement des espaces comme délimiteur.
La méthode la plus robuste, portable et efficace utilise également xargs:
find [whatever] -print0 | xargs -0 cat
L' -print0indicateur indique findd'utiliser des \0délimiteurs (caractère nul) entre les noms de fichiers, et l' -0indicateur indique xargsd'attendre ces \0délimiteurs. Cela a un comportement à peu près identique à l' approche -exec... +, bien qu'il soit plus portable (mais malheureusement plus verbeux).
ls.
$()également avec des commandes autres que find .
Cela me semble être un travail pour un script shell:
for file in 'find -name *.xml'
do
grep 'hello' file
done
ou quelque chose comme ça
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 ):
find . -exec grep "www.athabasca" '{}' \; -print
En bash, les éléments suivants seraient appropriés:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Cela trouvera tous les fichiers dans le /dirrépertoire et xargsdirigera les noms de fichiers en toute sécurité, qui conduiront en toute sécurité grep.
Ignorer xargsn'est pas une bonne idée si vous avez plusieurs milliers de fichiers dans /dir; catse cassera en raison de la longueur excessive de la liste des arguments. xargsva tout régler pour vous.
L' -print0argument à findmailles avec l' -0argument à xargspour gérer correctement les noms de fichiers avec des espaces. L' -iargument à xargsvous permet d'insérer le nom de fichier à l'endroit requis dans la catligne de commande. Les crochets sont remplacés par le nom de fichier redirigé vers la catcommande à partir de find.
Ça marche pour moi
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Utilisez ggrep .
ggrep -H -R -I "mysearchstring" *
rechercher un fichier sous unix contenant du texte situé dans le répertoire courant ou un sous-répertoire
Cela affichera le nom et le contenu des fichiers de manière récursive uniquement.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Modifier (version améliorée): Cela imprime le nom et le contenu des fichiers texte (ascii) de manière récursive uniquement.
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Encore une tentative
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Essayez-vous de trouver du texte dans des fichiers? Vous pouvez simplement utiliser grep pour cela ...
grep searchterm *
Pour lister et voir le contenu de tous les fichiers abc.def sur un serveur dans les répertoires / ghi et / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
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
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -printa très bien fonctionné pour moi ... Merci