j'ai des utilisateurs qui peuvent poser des fichiers dans un
repertoire.
Je souhaite ecrire un script qui scrute un repertoire et qui deplace
les fichiers ailleurs dans l'arborescence.
Je lancerai ce script via cron toutes les 15 minutes.
Je pensais faire un
#! /bin/bash
for file in `find /var/www/depot/ -type f`
do
mv $file /var/www/a_traiter/
done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers
n'importe comment (espace, ponctuation, caracteres speciaux) et il
arrive que le mv se plante.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Luc.Habert.00__arjf
:
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
.
octane@alinto.com :
for file in `find /var/www/depot/ -type f`
do
mv $file /var/www/a_traiter/
done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers
n'importe comment (espace, ponctuation, caracteres speciaux) et il
arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
.
octane
On 16 avr, 16:31, (Luc Habert) wrote:
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Entre autre je fais un echo "un fichier $file a ete transfere" et cron me maile le "echo", et je pense a terme faire des cas selon le fichier (exemple: .doc -> /dev/null, .pdf -> a_traiter/ etc etc..)
On 16 avr, 16:31, Luc.Habert.00__a...@normalesup.org (Luc Habert)
wrote:
for file in `find /var/www/depot/ -type f`
do
mv $file /var/www/a_traiter/
done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers
n'importe comment (espace, ponctuation, caracteres speciaux) et il
arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Entre autre je fais un
echo "un fichier $file a ete transfere"
et cron me maile le "echo", et je pense a terme faire des cas
selon le fichier (exemple: .doc -> /dev/null, .pdf -> a_traiter/
etc etc..)
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
Il suffit d'utiliser le -exec de find :
find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';'
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Entre autre je fais un echo "un fichier $file a ete transfere" et cron me maile le "echo", et je pense a terme faire des cas selon le fichier (exemple: .doc -> /dev/null, .pdf -> a_traiter/ etc etc..)
Luc.Habert.00__arjf
:
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton corps de boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en passe plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
octane@alinto.com :
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton corps de
boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en passe
plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton corps de boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en passe plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
octane
On 16 avr, 17:05, (Luc Habert) wrote:
:
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton cor ps de boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en p asse plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
Et je retombe sur mon probleme initial :) que dois-je mettre dans <corps de la boucle> pour que le mv me deplace les fichiers sans buter sur un fichier avec des caracteres speciaux? Plus, comment va se comporter le shell et le $@ avec des noms de fichiers avec des caracteres speciaux?
On 16 avr, 17:05, Luc.Habert.00__a...@normalesup.org (Luc Habert)
wrote:
oct...@alinto.com :
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton cor ps de
boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@";
do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en p asse
plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
Et je retombe sur mon probleme initial :)
que dois-je mettre dans <corps de la boucle> pour que le mv me
deplace les fichiers sans buter sur un fichier avec des caracteres
speciaux?
Plus, comment va se comporter le shell et le $@ avec des noms
de fichiers avec des caracteres speciaux?
oui, mais j'ai un peu plus de choses dans la boucle do .. done
Alors au lieu du mv, tu fais lancer à find un shell exécutant ton cor ps de boucle :
find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+'
(tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en p asse plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)).
Et je retombe sur mon probleme initial :) que dois-je mettre dans <corps de la boucle> pour que le mv me deplace les fichiers sans buter sur un fichier avec des caracteres speciaux? Plus, comment va se comporter le shell et le $@ avec des noms de fichiers avec des caracteres speciaux?
Luc.Habert.00__arjf
:
que dois-je mettre dans <corps de la boucle> pour que le mv me deplace les fichiers sans buter sur un fichier avec des caracteres speciaux?
Simplement mettre « "$file" » au lieu de « $file ».
En fait, ce qui se passait avec ce que tu faisais, c'est que dans ton
for file in `find /var/www/depot/ -type f`
le shell lit la sortie de find, la découpe sur le whitespace (plus précisément les caractères contenus dans la variable IFS qui, par défaut, contient le whitespace), et ensuite fait du globbing (interprétation des * et cie) sur chaque morceau. Avec ce que je t'indique, ce découpage est éliminé : l'écriture « "$@" » est spéciale, elle spécifie que ça donne la liste des arguments passés au script, sans découpage ni globbing. Il reste juste à ce que le « $file » ne se fasse pas découper dans le corps de la boucle, et pour ça, il faut et il suffit de le mettre entre « " » à chaque fois où tu t'en sers.
On ne le répètera jamais assez : il faut toujours mettre entre « " » les expansions de variables, sauf si on veut vraiment du découpage et du globbing, ce qui n'arrive pas si souvent que ça. (Et si on ne veut que l'un des deux? Pour désactiver le découpage, il faut vider IFS, et pour désactiver le globbing, il faut faire un « set -f ».)
octane@alinto.com :
que dois-je mettre dans <corps de la boucle> pour que le mv me
deplace les fichiers sans buter sur un fichier avec des caracteres
speciaux?
Simplement mettre « "$file" » au lieu de « $file ».
En fait, ce qui se passait avec ce que tu faisais, c'est que dans ton
for file in `find /var/www/depot/ -type f`
le shell lit la sortie de find, la découpe sur le whitespace (plus
précisément les caractères contenus dans la variable IFS qui, par défaut,
contient le whitespace), et ensuite fait du globbing (interprétation des *
et cie) sur chaque morceau. Avec ce que je t'indique, ce découpage est
éliminé : l'écriture « "$@" » est spéciale, elle spécifie que ça donne la
liste des arguments passés au script, sans découpage ni globbing. Il reste
juste à ce que le « $file » ne se fasse pas découper dans le corps de la
boucle, et pour ça, il faut et il suffit de le mettre entre « " » à chaque
fois où tu t'en sers.
On ne le répètera jamais assez : il faut toujours mettre entre « " » les
expansions de variables, sauf si on veut vraiment du découpage et du
globbing, ce qui n'arrive pas si souvent que ça. (Et si on ne veut que l'un
des deux? Pour désactiver le découpage, il faut vider IFS, et pour
désactiver le globbing, il faut faire un « set -f ».)
que dois-je mettre dans <corps de la boucle> pour que le mv me deplace les fichiers sans buter sur un fichier avec des caracteres speciaux?
Simplement mettre « "$file" » au lieu de « $file ».
En fait, ce qui se passait avec ce que tu faisais, c'est que dans ton
for file in `find /var/www/depot/ -type f`
le shell lit la sortie de find, la découpe sur le whitespace (plus précisément les caractères contenus dans la variable IFS qui, par défaut, contient le whitespace), et ensuite fait du globbing (interprétation des * et cie) sur chaque morceau. Avec ce que je t'indique, ce découpage est éliminé : l'écriture « "$@" » est spéciale, elle spécifie que ça donne la liste des arguments passés au script, sans découpage ni globbing. Il reste juste à ce que le « $file » ne se fasse pas découper dans le corps de la boucle, et pour ça, il faut et il suffit de le mettre entre « " » à chaque fois où tu t'en sers.
On ne le répètera jamais assez : il faut toujours mettre entre « " » les expansions de variables, sauf si on veut vraiment du découpage et du globbing, ce qui n'arrive pas si souvent que ça. (Et si on ne veut que l'un des deux? Pour désactiver le découpage, il faut vider IFS, et pour désactiver le globbing, il faut faire un « set -f ».)
Mihamina (R12y) Rakotomandimby
Luc Habert - <f003cm$cj0$ :
j'avais mis un « ; », mais mieux vaut un « +
J'ai regardé dans le man find ce que ça signifiait. Pas trouvé. Dans le man du shell (bash)? Trop "long"... Un coup de main?
Luc Habert - <f003cm$cj0$4@nef.ens.fr> :
j'avais mis un « ; », mais mieux vaut un « +
J'ai regardé dans le man find ce que ça signifiait. Pas trouvé. Dans le man
du shell (bash)? Trop "long"... Un coup de main?
Ne marche que quand + est l'argument suivant le {} et s'il n'y a qu'un seul {}. Et ca remplace {} par autant de fichiers que possibles. C'est la version standard du -print0 | xargs -r0 de GNU en mieux car il n'affecte pas le stdin des commandes (cela dit, il pourra etre moins efficace car s'il y a plusieurs commandes lancees, find ne continuera pas sa descente pendant que les commandes sont executees).
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans et que ca existe depuis 20, je crois que GNU find ne l'a inclu que tres recemment, ca explique peut-etre pourquoi ca n'est pas dans ta page de man.
Ne marche que quand + est l'argument suivant le {} et s'il n'y a
qu'un seul {}. Et ca remplace {} par autant de fichiers que
possibles. C'est la version standard du -print0 | xargs -r0 de
GNU en mieux car il n'affecte pas le stdin des commandes (cela
dit, il pourra etre moins efficace car s'il y a plusieurs
commandes lancees, find ne continuera pas sa descente pendant
que les commandes sont executees).
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans
et que ca existe depuis 20, je crois que GNU find ne l'a inclu
que tres recemment, ca explique peut-etre pourquoi ca n'est pas
dans ta page de man.
Ne marche que quand + est l'argument suivant le {} et s'il n'y a qu'un seul {}. Et ca remplace {} par autant de fichiers que possibles. C'est la version standard du -print0 | xargs -r0 de GNU en mieux car il n'affecte pas le stdin des commandes (cela dit, il pourra etre moins efficace car s'il y a plusieurs commandes lancees, find ne continuera pas sa descente pendant que les commandes sont executees).
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans et que ca existe depuis 20, je crois que GNU find ne l'a inclu que tres recemment, ca explique peut-etre pourquoi ca n'est pas dans ta page de man.
-- Stéphane
Nicolas George
Stephane Chazelas wrote in message :
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans et que ca existe depuis 20, je crois que GNU find ne l'a inclu que tres recemment, ca explique peut-etre pourquoi ca n'est pas dans ta page de man.
Plus précisément, le ChangeLog indique que ça a commencé à fonctionner le 2005-01-15, et que c'est sorti dans la version 4.2.12.
Stephane Chazelas wrote in message
<slrnf2bh9o.5t4.stephane.chazelas@spam.is.invalid>:
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans
et que ca existe depuis 20, je crois que GNU find ne l'a inclu
que tres recemment, ca explique peut-etre pourquoi ca n'est pas
dans ta page de man.
Plus précisément, le ChangeLog indique que ça a commencé à fonctionner le
2005-01-15, et que c'est sorti dans la version 4.2.12.
Bien que -exec ... {} + ait ete dans le standard depuis 15 ans et que ca existe depuis 20, je crois que GNU find ne l'a inclu que tres recemment, ca explique peut-etre pourquoi ca n'est pas dans ta page de man.
Plus précisément, le ChangeLog indique que ça a commencé à fonctionner le 2005-01-15, et que c'est sorti dans la version 4.2.12.
Cyrille Lefevre
Bonjour,
j'ai des utilisateurs qui peuvent poser des fichiers dans un repertoire. Je souhaite ecrire un script qui scrute un repertoire et qui deplace les fichiers ailleurs dans l'arborescence. Je lancerai ce script via cron toutes les 15 minutes.
Je pensais faire un #! /bin/bash
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
si find supporte -print0 et xargs -0 (zero), le plus simple est :
find /var/depot/www | while read line; do mv "${line}" /var/www/a_traiter done
le pb etant le nombre d'execution de la commande mv, 1 par fichier, optimisons donc un peu (a la xargs) :
find /var/depot/www -type f | # remplacement de tous les " par " sed -e 's/"/&/g' | ( # longueur maximale de la ligne de commande limit000 # valeur initiale args=mv while read line; do # si la limite est atteinte if (( ${#args} + ${#line} + 1 > ${limit} )); then # execution de la ligne de commande prepare eval ${args} /var/www/a_traiter # puis reinitialisation args=mv # pas de continue pour ne pas perdre l'argument courant fi # ajout de l'argument courant a la ligne de commande a executer args="${args} "${line}"" done # traitement de ce qui reste eval ${args} /var/www/a_traiter )
non verifie, mais je ne dois pas etre loin de la verite :) de toutes les facons, s'il y a un bug, c'est un bon exercice...
Regards, Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre. remove "%nospam" and ".invalid" to answer me.
Bonjour,
j'ai des utilisateurs qui peuvent poser des fichiers dans un
repertoire.
Je souhaite ecrire un script qui scrute un repertoire et qui deplace
les fichiers ailleurs dans l'arborescence.
Je lancerai ce script via cron toutes les 15 minutes.
Je pensais faire un
#! /bin/bash
for file in `find /var/www/depot/ -type f`
do
mv $file /var/www/a_traiter/
done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers
n'importe comment (espace, ponctuation, caracteres speciaux) et il
arrive que le mv se plante.
si find supporte -print0 et xargs -0 (zero), le plus simple est :
find /var/depot/www |
while read line; do
mv "${line}" /var/www/a_traiter
done
le pb etant le nombre d'execution de la commande mv,
1 par fichier, optimisons donc un peu (a la xargs) :
find /var/depot/www -type f |
# remplacement de tous les " par "
sed -e 's/"/\&/g' |
(
# longueur maximale de la ligne de commande
limit000
# valeur initiale
args=mv
while read line; do
# si la limite est atteinte
if (( ${#args} + ${#line} + 1 > ${limit} )); then
# execution de la ligne de commande prepare
eval ${args} /var/www/a_traiter
# puis reinitialisation
args=mv
# pas de continue pour ne pas perdre l'argument courant
fi
# ajout de l'argument courant a la ligne de commande a executer
args="${args} "${line}""
done
# traitement de ce qui reste
eval ${args} /var/www/a_traiter
)
non verifie, mais je ne dois pas etre loin de la verite :)
de toutes les facons, s'il y a un bug, c'est un bon exercice...
Regards, Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
remove "%nospam" and ".invalid" to answer me.
j'ai des utilisateurs qui peuvent poser des fichiers dans un repertoire. Je souhaite ecrire un script qui scrute un repertoire et qui deplace les fichiers ailleurs dans l'arborescence. Je lancerai ce script via cron toutes les 15 minutes.
Je pensais faire un #! /bin/bash
for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done
Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante.
si find supporte -print0 et xargs -0 (zero), le plus simple est :
find /var/depot/www | while read line; do mv "${line}" /var/www/a_traiter done
le pb etant le nombre d'execution de la commande mv, 1 par fichier, optimisons donc un peu (a la xargs) :
find /var/depot/www -type f | # remplacement de tous les " par " sed -e 's/"/&/g' | ( # longueur maximale de la ligne de commande limit000 # valeur initiale args=mv while read line; do # si la limite est atteinte if (( ${#args} + ${#line} + 1 > ${limit} )); then # execution de la ligne de commande prepare eval ${args} /var/www/a_traiter # puis reinitialisation args=mv # pas de continue pour ne pas perdre l'argument courant fi # ajout de l'argument courant a la ligne de commande a executer args="${args} "${line}"" done # traitement de ce qui reste eval ${args} /var/www/a_traiter )
non verifie, mais je ne dois pas etre loin de la verite :) de toutes les facons, s'il y a un bug, c'est un bon exercice...
Regards, Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre. remove "%nospam" and ".invalid" to answer me.