J'essaie d'écrire un script bash qui traitera une liste de fichiers dont les noms sont stockés un par ligne dans un fichier d'entrée, quelque chose comme
find . -type f -mtime +15 > /tmp/filelist.txt
for F in $(cat /tmp/filelist.txt) ; do
...
done;
Mon problème est que les noms de fichiers dans filelist.txt peuvent contenir des espaces, donc l'extrait ci-dessus étendra la ligne
my text file.txt
à trois noms de fichiers différents, my
, text
et file.txt
. Comment puis-je résoudre ce problème?
Utilisez read
:
while read F ; do
echo $F
done </tmp/filelist.txt
Vous pouvez également utiliser IFS pour modifier la façon dont le shell sépare votre liste:
OLDIFS=$IFS
IFS="
"
for F in $(cat /tmp/filelist.txt) ; do
echo $F
done
IFS=$OLDIFS
Alternativement (comme suggéré par @tangens), convertissez le corps de votre boucle en un script séparé, puis utilisez l'option -exec de find
pour l'exécuter si pour chaque fichier trouvé directement.
Vous pouvez le faire sans fichier temporaire en utilisant la substitution de processus:
while read F
do
...
done < <(find . -type f -mtime +15)
utiliser pendant la lecture
echo $FILE | while read line
do
echo $line
done
Vous pouvez faire une redirection au lieu d'un écho
Vous pouvez utiliser le -exec
paramètre de find
et utilisez directement les noms de fichiers:
find . -type f -mtime +15 -exec <your command here> {} \;
Le {}
est un espace réservé pour le nom de fichier.
redirigez votre commande find directement vers la boucle de lecture
find . -type f -mtime +15 | while read -r line
do
printf "do something with $line\n"
done
Je ne suis en aucun cas un expert bash (j'écris habituellement mon script en Ruby ou python pour être multiplateforme), mais j'utiliserais un expression rationnelle pour échapper aux espaces de chaque ligne avant de la traiter.
Pour Bash Regex: http://www.linuxjournal.com/node/1006996
Dans une situation similaire en Ruby (traitement d'un fichier csv et nettoyage de chaque ligne avant de l'utiliser)):
File.foreach(csv_file_name) do |line|
clean_line = line.gsub(/( )/, '\ ')
#this finds the space in your file name and escapes it
#do more stuff here
end