Mon meilleur pari actuel est:
for i in $(find . -name *.jpg); do echo $i; done
Problème: ne gère pas les espaces dans les noms de fichiers.
Remarque: j'aimerais également une manière graphique de faire cela, comme la commande "tree".
Mon meilleur pari actuel est:
for i in $(find . -name *.jpg); do echo $i; done
Problème: ne gère pas les espaces dans les noms de fichiers.
Remarque: j'aimerais également une manière graphique de faire cela, comme la commande "tree".
Réponses:
La voie canonique est de faire
find . -name '*.jpg' -exec echo {} \;
(remplacez \;
par +
pour transmettre plusieurs fichiers echo
à la fois)
ou (spécifique à GNU, bien que certains BSD l'aient également):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
ce qui étend les séquences d'échappement comme \b
(au moins les conformes Unix echo
).
find
page de manuel s'affiche find . -type f -exec file '{}' \;
dans la EXAMPLES
section. Peut-être que certaines coquilles traiteront spécialement les accolades.
'{}'
, \{\}
, {}
, "{}"
, '{'}
sont complétés par le shell (quelle que soit Bourne shell-like) à un argument de constater que les deux personnages est « { » et « } ». Remplacez "find" par "echo find", ou printf '<%s>\n' find
si vous souhaitez revérifier.
De meilleures réponses ont déjà été données.
Mais notez que les espaces ne sont pas le seul problème dans le code que vous avez donné. les caractères de tabulation, de nouvelle ligne et de caractère générique sont également un problème.
Avec
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
Ensuite, seuls les caractères de nouvelle ligne posent problème.
Ce que vous avez mentionné est l'un des problèmes fondamentaux auxquels les gens sont confrontés lorsqu'ils essaient de lire les noms de fichiers. Parfois, les personnes ayant des connaissances limitées et ayant une conception erronée de la structure des fichiers et des dossiers ont tendance à oublier que " Sous UNIX, tout est un fichier ". Ils ne comprennent donc pas qu'ils doivent également gérer les espaces, car le nom de fichier peut être composé de 2 mots ou plus avec des espaces.
Solution: l' une des façons les plus connues de procéder consiste à effectuer une lecture claire .
Nous allons ici lire tous les fichiers présents et les conserver dans une variable, la prochaine fois lors du traitement souhaité, nous devrons simplement garder cette variable entre guillemets qui préservera les noms de fichiers avec des espaces. C'est l'un des moyens de base de le faire, cependant, les autres réponses fournies par les autres personnes ici fonctionnent tout aussi bien.
SCRIPT:
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
Ici, je lis les fichiers en leur donnant le chemin d'accès et tout ce que je lis, je les garde dans une variable I, que je citerai plus tard en le traitant pour conserver les espaces afin de le traiter correctement.
J'espère que cela vous aide d'une manière ou d'une autre.
Simplement avec find
et bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
De cette façon, nous utilisons $1
en bash, comme dans un script de base, qui ouvrent de belles perspectives pour effectuer toutes les tâches avancées (ou non).
Un moyen plus efficace (pour éviter d'avoir à démarrer un nouveau bash pour chaque fichier):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
Dans la version récente de bash, vous pouvez utiliser l' globstar
option:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Pour les actions simples, vous pouvez même ignorer complètement la boucle:
echo **/*.jpg
set -G
), il ne devrait pas être utilisé dans bash car la version bash est fondamentalement cassée (tout comme GNU grep -r
) car elle descend en liens symboliques vers des répertoires (équivalents à find -L
ou zsh) ***/*.jpg
). Notez également que contrairement à find, il supprimera les dotfiles et ne descendra pas dans les dotdirs (par défaut).
$i
? Je fais ça et ça marche bien. Y a-t-il un problème avec cette approche?