Parfois, je vois la commande suivante:
find . -name * -exec ls -a {} \;
On m'a demandé d'exécuter ceci.
Que {} \;
signifie ici?
command-line
find
code de noeud
la source
la source
-name *
est redondant.-name *
est pire que redondant. Parce que le*
n'est pas entre guillemets, le shell le développe pour former la liste des noms de fichiers du dossier en cours, les espaces étant traités de manière incorrecte, ce qui entraîne des résultats inattendus ou un message d'erreur. Un point supplémentairefind
a de nombreuses fonctions, l’une d’eux étant de lister les fichiers; cela évite d'avoir à utiliser-exec
. Par exemple, vous pouvez utiliserfind . -print
oufind . -ls
. Enfin, il y a deux façons d'échapper à la demi-virgule: soit comme vous avez fait avec la barre oblique inverse,\;
ou en citant:';'
. Utilisez celui avec lequel vous vous sentez le plus à l'aise.Réponses:
Si vous exécutez
find
avecexec
,{}
étend le nom de fichier de chaque fichier ou répertoire trouvé avecfind
(pour quels
dans votre exemple, chaque nom de fichier trouvé soit considéré comme un argument - notez qu'il appellels
ou toute autre commande spécifiée une fois pour chaque fichier trouvé).Le point-virgule
;
met fin à la commande exécutée parexec
. Il doit être échappé avec\
pour que le shell dans lequel vous courezfind
ne le traite pas comme son propre caractère spécial, mais le transmette àfind
.Voir cet article pour plus de détails.
En outre,
find
fournit une optimisation avecexec cmd {} +
- lorsque exécuté comme cela,find
ajoute les fichiers trouvés à la fin de la commande plutôt que de les invoquer une fois par fichier (pour que la commande ne soit exécutée qu'une fois, si possible).La différence de comportement (sinon d'efficacité) est facilement perceptible si elle est exécutée avec
ls
, par exempleEn supposant que vous ayez des
jpg
fichiers (avec des chemins suffisamment courts ), le résultat est une ligne par fichier dans le premier cas et unls
comportement standard d'affichage des fichiers en colonnes pour ce dernier.la source
\;
avec+
.find . -name * | ls -a -
?find
. De plus, la sortie dels
dans ce cas ne dépend apparemment pas de l'entrée - peu importe le filtre que j'utilisefind
,ls
affiche simplement le contenu du répertoire de travail et c'est tout. Consultez par exemplefind ~ -iname '*.jpg' -exec ls -a {} \;
vsfind ~ -iname '*.jpg' | ls -a
.echo 'foo' | ls -a
.-
dans votrels -a -
commande lorsque vous testez ce que @ dr-h a demandé.Depuis la page de manuel de la
find
commande :Alors voici l'explication:
{}
signifie "la sortie defind
". Comme dans "tout ce qui estfind
trouvé".find
renvoie le chemin du fichier que vous recherchez, non? Alors le{}
remplace; c'est un espace réservé pour chaque fichier que lafind
commande localise (pris à partir d' ici ).La
\;
partie dit essentiellementfind
"d'accord, j'ai fini avec la commande que je voulais exécuter".Exemple:
Disons que je suis dans un répertoire plein de
.txt
fichiers. Je cours ensuite:La première partie,
find . -name *.txt
renvoie la liste des.txt
fichiers. La deuxième partie-exec cat {} \;
exécutera lacat
commande pour chaque fichier trouvé parfind
, etc.cat file1.txt
,cat file2.txt
etc.la source
*.txt
doit être citée comme'*.txt'
. En effet, s’il existe des.txt
fichiers dans le dossier actuel, le shell le développera et vous obtiendrez des résultats incorrects ou un message d’erreur.find -name '*.txt' -exec cat {} \;