Je sais que c'est un vieux fil, mais je suis tombé dessus et j'ai pensé partager ma méthode que j'ai trouvée être un moyen très rapide d'utiliser find
pour ne trouver que des fichiers non binaires:
find . -type f -exec grep -Iq . {} \; -print
L' -I
option de grep lui dit d'ignorer immédiatement les fichiers binaires et l' .
option avec le -q
le fera correspondre immédiatement aux fichiers texte, donc cela va très vite. Vous pouvez changer le -print
en un -print0
pour faire passer un xargs -0
ou quelque chose si vous êtes préoccupé par les espaces (merci pour le conseil, @ lucas.werkmeister!)
De plus, le premier point n'est nécessaire que pour certaines versions de BSD find
, comme sur OS X, mais cela ne fait pas de mal de l'avoir là tout le temps si vous voulez le mettre dans un alias ou quelque chose.
EDIT : Comme @ruslan l'a correctement souligné, le -and
peut être omis car il est implicite.
find . -type f -exec grep -Il "" {} \;
.find -type f -exec grep -Iq . {} \; -and -print
ce qui a l'avantage de conserver les fichiersfind
; vous pouvez le remplacer-print
par un autre-exec
qui n'est exécuté que pour les fichiers texte. (Si vous laissezgrep
imprimer les noms de fichiers, vous ne pourrez pas distinguer les noms de fichiers avec des sauts de ligne.)find . -type f -exec grep -Il . {} +
est beaucoup plus rapide. L'inconvénient est qu'il ne peut pas être prolongé par un autre-exec
comme le suggère @ lucas.werkmeisterSur la base de cette question SO :
grep -rIl "needle text" my_folder
la source
-I
c'est une bouée de sauvetage.Pourquoi est-ce peu pratique? Si vous avez besoin de l'utiliser souvent et que vous ne voulez pas le saisir à chaque fois, définissez simplement une fonction bash pour lui:
mettez-le dans votre
.bashrc
puis exécutez simplement:quand tu veux.
MODIFIER pour refléter la modification d'OP:
si vous voulez supprimer les informations mime, vous pouvez simplement ajouter une étape supplémentaire au pipeline qui filtre les informations mime. Cela devrait faire l'affaire, en ne prenant que ce qui vient avant
:
:cut -d':' -f1
:la source
file
manuel: "Les utilisateurs doivent savoir que tous les fichiers lisibles dans un répertoire ont le mot" texte "imprimé."/proc/meminfo
,/proc/cpuinfo
etc. sont des fichiers texte, maisfile /proc/meminfo
dit/proc/meminfo: empty
. Je me demande si «vide» devrait être testé en plus de «texte», mais je ne sais pas si d'autres types pourraient également signaler «vide».Ce n'est malheureusement pas un gain de place. Mettre cela dans le script bash rend les choses un peu plus faciles.
Ceci est sans danger pour l'espace:
la source
text.bin
? 2. Que faire si un nom de fichier contient un:
?Une autre façon de procéder:
Si vous voulez aussi des fichiers vides:
la source
Que dis-tu de ça:
Si vous voulez les noms de fichiers sans les types de fichiers, ajoutez simplement un
sed
filtre final .Vous pouvez filtrer les types de fichiers inutiles en ajoutant plus d'
-e 'type'
options à la dernièregrep
commande.ÉDITER:
Si votre
xargs
version prend en charge l'-d
option, les commandes ci-dessus deviennent plus simples:la source
Voici comment je l'ai fait ...
1 . faire un petit script pour tester si un fichier est en texte brut istext:
2. utilisez find comme avant
la source
== *"text"* ]]
?J'ai deux problèmes avec la réponse de l'histumness:
Il ne répertorie que les fichiers texte. Il ne les recherche pas réellement comme demandé. Pour effectuer une recherche, utilisez
Il génère un processus grep pour chaque fichier, ce qui est très lent. Une meilleure solution est alors
ou simplement
Cela ne prend que 0,2s contre 4s pour la solution ci-dessus (2,5 Go de données / 7700 fichiers), soit 20x plus rapide .
De plus, personne n'a cité ag, le Silver Searcher ou ack-grep ¸ comme alternatives. Si l'un d'entre eux est disponible, ce sont de bien meilleures alternatives:
En dernier lieu, méfiez - vous des faux positifs (fichiers binaires pris comme fichiers texte). J'avais déjà des faux positifs en utilisant soit grep / ag / ack, donc mieux vaut lister les fichiers correspondants avant de les éditer.
la source
Bien que ce soit une vieille question, je pense que cette info ci-dessous ajoutera à la qualité des réponses ici.
Lorsque vous ignorez les fichiers avec le bit exécutable défini, j'utilise simplement cette commande:
Pour l'empêcher d'entrer récursivement dans d'autres répertoires:
Pas besoin de tubes pour mélanger beaucoup de commandes, juste la puissante commande plain find .
Cela dit, j'espère que cela sera utile à tout le monde.
la source
Je le fais de cette façon: 1) comme il y a trop de fichiers (~ 30k) à rechercher, je génère la liste des fichiers texte quotidiennement pour une utilisation via crontab en utilisant la commande ci-dessous:
2) créez une fonction dans .bashrc:
Ensuite, je peux utiliser la commande ci-dessous pour effectuer la recherche:
HTH :)
la source
Je préfère xargs
si vos noms de fichiers sont bizarres, recherchez en utilisant les options -0:
la source
grep eth0 $ (trouver / etc / -type f -exec file {} \; | egrep -i "texte | ascii" | cut -d ':' -f1)
la source
Voici une version simplifiée avec des explications étendues pour les débutants comme moi qui essaient d'apprendre à mettre plus d'une commande sur une ligne.
Si vous deviez écrire le problème par étapes, cela ressemblerait à ceci:
Pour ce faire , on peut utiliser trois commandes UNIX:
find
,file
etgrep
.find
vérifiera tous les fichiers du répertoire.file
nous donnera le type de fichier. Dans notre cas, nous recherchons un retour de 'texte ASCII'grep
cherchera le mot-clé 'ASCII' dans la sortie defile
Alors, comment pouvons-nous les assembler en une seule ligne? Il y a plusieurs façons de le faire, mais je trouve que le faire dans l'ordre de notre pseudo-code a le plus de sens (surtout pour un débutant comme moi).
find ./ -exec file {} ";" | grep 'ASCII'
Ça a l'air compliqué, mais pas mal quand on le décompose:
find ./
= parcourez tous les fichiers de ce répertoire. Lafind
commande imprime le nom de fichier de tout fichier qui correspond à l'expression, ou tout ce qui vient après le chemin, qui dans notre cas est le répertoire courant ou./
La chose la plus importante à comprendre est que tout ce qui suit ce premier bit sera évalué comme vrai ou faux. Si True, le nom du fichier sera imprimé. Sinon, la commande continue.
-exec
= cet indicateur est une option dans la commande find qui nous permet d'utiliser le résultat d'une autre commande comme expression de recherche. C'est comme appeler une fonction dans une fonction.file {}
= la commande appelée à l'intérieur defind
. Lafile
commande renvoie une chaîne qui vous indique le type de fichier d'un fichier. Régulièrement, il ressemblerait à ceci:file mytextfile.txt
. Dans notre cas, nous voulons qu'il utilise n'importe quel fichier examiné par lafind
commande, nous mettons donc les accolades{}
pour agir comme une variable ou un paramètre vide. En d'autres termes, nous demandons simplement au système de générer une chaîne pour chaque fichier du répertoire.";"
= ceci est requis parfind
et est le signe de ponctuation à la fin de notre-exec
commande. Voir le manuel pour «trouver» pour plus d'explications si vous en avez besoin en exécutantman find
.| grep 'ASCII'
=|
est un tuyau. Le tuyau prend la sortie de ce qui se trouve à gauche et l'utilise comme entrée pour ce qui se trouve à droite. Il prend la sortie de lafind
commande (une chaîne qui est le type de fichier d'un seul fichier) et la teste pour voir si elle contient la chaîne'ASCII'
. Si c'est le cas, il renvoie vrai.MAINTENANT, l'expression à droite de
find ./
retournera true lorsque lagrep
commande retourne true. Voila.la source
Si vous souhaitez trouver n'importe quel type de fichier par ses octets magiques en utilisant l'
file
utilitaire génial combiné à la puissance defind
, cela peut être utile:Production:
Légende:
$
est l'invite du shell interactif où nous entrons nos commandesVous pouvez modifier la partie après
&&
pour appeler un autre script ou faire d'autres choses en ligne également, c'est-à-dire si ce fichier contient une chaîne donnée, insérez le fichier entier ou recherchez une chaîne secondaire.Explication:
find
éléments qui sont des fichiersxargs
alimenter chaque élément sous forme de ligne dans unebash
commande / script de lignefile
vérifie le type de fichier par octet magique,grep
vérifie si ASCII existe, si c'est le cas, puis après&&
l'exécution de la commande suivante.find
imprime les résultatsnull
séparés, c'est bien pour échapper les noms de fichiers avec des espaces et des méta-caractères.xargs
, en utilisant l'-0
option, les litnull
séparément,-I @@
prend chaque enregistrement et utilise comme paramètre de position / args pour bash script.--
carbash
garantit que tout ce qui vient après est un argument même s'il commence par-
like-c
qui pourrait autrement être interprété comme une option bashSi vous avez besoin de trouver des types autres que ASCII, remplacez simplement
grep ASCII
par un autre type, commegrep "PDF document, version 1.4"
la source
Utilisez la commande find pour lister tous les fichiers, utilisez la commande file pour vérifier qu'il s'agit de texte (pas tar, key), enfin utilisez la commande awk pour filtrer et imprimer le résultat.
la source
Que dis-tu de ça
la source
"needle text"
"needl text"
"needle text"
il serait trouvé