Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/09/2016, à 12:32

abach

[Résolu] Espaces dans des noms de dossiers et de fichiers

Bonjour à tous et à toutes,

J'ai un problème que je n'arrive pas à résoudre. En fait, je ne sais même plus par quel bout le prendre.

J'ai des fichiers qui arrivent automatiquement dans une arborescence, créée elle aussi automatiquement, via un transfert FTP.

Ces fichiers sont des images et des vidéos provenant d'appareils de mesure. Les vidéos étant des avi et mon appli devant les visualiser ne gérant que les flv, j'ai écrit un script, basé sur ffmpeg, les transformant automatiquement. Ca marche bien, sauf que mon script ne gère pas les noms avec des espaces...

Le script, le voici :

#!/bin/bash
clear
PIDFILE=/tmp/.appli.pid
source=/media/abach/mediacenter/cameras
destination=/media/abach/raspdisk/www/appli/galleries
sourcefile="./.src.log"
radsource="$source/"
raddestination="$destination/"
logfile=$HOME/appli.log


	function x1
	{
		echo "$1 `date +"%d/%m/%Y  %H:%M:%S"`" >> $2
	}

	function xxx
	{
		chaine=${3#$1};
		result=${chaine%$2};
		echo "$result" >> "$4"
	}
	function decimal
	{
		res=`bc <<< "scale = 1; ( $1 / 10)"`
		resdecimal="${res: -2}"
		echo $resdecimal
	}


	function xfert
	{
		rsync -arz --exclude *.mp4 --exclude *.avi --exclude *.log --delete-after $1 $2
	}

	export -f decimal
	export -f x1
	export -f xxx
	export -f xfert

if [ -f $PIDFILE ]
then
  PID=$(cat $PIDFILE)
  ps -p $PID > /dev/null 2>&1
  if [ $? -eq 0 ]
  then
	x1 $logfile
    x1 "Job is already running " $logfile
    exit 1
  else
    ## Process not found assume not running
    echo $$ > $PIDFILE
    if [ $? -ne 0 ]
    then
	  x1 $logfile
      echo "Could not create PID file" >> $logfile
      exit 1
    fi

  fi
else
  echo $$ > $PIDFILE
  if [ $? -ne 0 ]
  then
	x1 $logfile
    echo "Could not create PID file" >> $logfile
    exit 1
  fi
	declare -a srcarray
	# declare -a destarray

	rm $sourcefile
	# rm $destfile
	rm $logfile
	echo $radsource

	x1 "appli.sh           :  " $logfile
    x1 "====================   "   $logfile
	xfert $radsource $raddestination
	x1 "Début               :  " $logfile
	x1 "source              :  " $logfile
	echo "source"
	find $source -name '*.avi' -exec bash -c 'xxx '$radsource' ".avi" "$0" '$sourcefile' ' {} \; ;

	x1 "Tableaux            :  " $logfile
	echo "tableau"
	x1 "     source         :  " $logfile
	echo "-- source"
	index=0
	for w in $(cat "$sourcefile"); 
	do
		srcarray[index]="$w"
		index=$(expr $index + 1)
	done
	echo "--"
	x1 "Tableau             :  " $logfile
	echo "done"
	echo "${#srcarray[@]} - ${#destarray[@]}" >> $logfile
	echo "${#srcarray[@]} - ${#destarray[@]}"
	x1 "Conversion          :  " $logfile
	compteboucle=0
	compteaction=0
	for iii in "${srcarray[@]}"
	do
		((compteboucle++))
		entree="$iii"
		insource=0
		if [ -f "$radsource$entree.avi" ] && [ ! -f "$radsource$entree.flv" ];
		then
			((compteaction++))
			echo -n "$compteboucle-$compteaction : $radsource$entree.flv n'existe pas - "
			/usr/bin/ffmpeg -y -i "$radsource$entree.avi" -vcodec flv -f flv -r 29.97 -filter:v scale=w=640:h=480 -aspect 4:3 -b:v 300k -g 160 -cmp dct  -subcmp dct  -mbd 2 -flags +aic+mv0+mv4 -trellis 1 -ac 1 -ar 22050 -b:a 56k "$radsource$entree.flv" >/dev/null 2>&1
			echo "ok"
		fi
			echo "ok"
		fi
		cpt=$(decimal $compteaction)
		if [ "$cpt" = ".0" ]
		then
			xfert $radsource $raddestination
		fi
		# test=$(echo "scale=1; $1/3" | bc)
	done
	find $source -name "*.avi" -type f -delete ;
	x1 "Conversion          :  " $logfile
	x1 "Transfert           :  " $logfile
	xfert $radsource $raddestination
	x1 "Transfert           :  " $logfile
	# rsync -avrz --delete-after -L $source/*.jpg $destination
	rm $PIDFILE
	echo "$PIDFILE removed"
fi

Ma question du jour est de savoir comment gérer les noms de fichiers et de répertoire contenant des espaces...
J'ai cherché et j'ai trouvé des trucs avec "\042" mais rien à faire, je n'y arrive pas.
J'ai aussi cherché à tout renommer, fichiers et dossiers, via des mv, des sed... là encore sans résultat.

Si quelqu'un à une idée, je lui en suis d'avance reconnaissant.

Dernière modification par abach (Le 24/09/2016, à 12:26)


Les chiens vous regardent tous avec vénération. Les chats vous toisent tous avec dédain. Il n’y a que les cochons qui vous considèrent comme leurs égaux. - Winston Churchill
Je suis parrain Linux

Hors ligne

#2 Le 14/09/2016, à 12:39

pingouinux

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Bonjour,
Peux-tu préciser dans quelle partie du script le problème apparaît ? D'une façon générale, il faut utiliser des " ".

$ fichier="mon   fichier   avec   des   espaces"
$ echo "$fichier"
mon   fichier   avec   des   espaces

Dernière modification par pingouinux (Le 14/09/2016, à 12:40)

Hors ligne

#3 Le 14/09/2016, à 12:53

abach

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Un exemple est plus parlant :

/dossier/dossier 1
                  /fichier 1 plus un truc.avi
                  /fichier 2 avec autre chose.mp3
                  /file 4 xxx y ssss.jpg
        /dossier numero 2

Tu vois, c'est pas fixe et ça dépend des sources...
Les espaces sont à la fois dans l'arborescence de répertoires et dans les noms de fichiers. J'ai aussi, bien sûr, pour compliquer le tout, plusieurs niveaux dans l'arborescence. C'est pour ça que find me semblait une bonne source de départ.


Les chiens vous regardent tous avec vénération. Les chats vous toisent tous avec dédain. Il n’y a que les cochons qui vous considèrent comme leurs égaux. - Winston Churchill
Je suis parrain Linux

Hors ligne

#4 Le 14/09/2016, à 12:58

grigouille

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Change IFS.
Par exemple, met

IFS='|'
$ ls -1
a b.txt
test.sh
$ cat test.sh 
#/bin/bash
IFS='|'
for f in $(ls)
do
	echo $f
done
$ ./test.sh 
a b.txt
test.sh
$ 

Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#5 Le 14/09/2016, à 13:37

Watael

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

modifier l'IFS, mais que c'est laid ! en plus, tu ne le restaureS même pas !
et les guillemets autour des variables !?

salut abach,

attention, ligne 116, il y a un fi qui semble ne dépendre d'aucun if.

pour lire un fichier, on utilise une boucle while :

while read line; do echo "$line"; done

pour gérer les espaces dans les noms de fichiers, je vois deux solutions :
- faire afficher, par find, la liste des noms des fichiers séparés par NULL avec -print0, et piper cette sortie à une boucle while
l'intervention d'un tableau est-elle nécessaire ?
par exemple :

 find ~ -maxdepth 1 -type f -print0 | while read -d '' filename; do : whatever with " $filename"; done

- positionner les options du shell nullglob (au cas où il n'y aurait pas de fichier) et globstar (pour descendre dans les sous-répertoires :

for f in "$src"/**/*.avi; do : whatever with "$f"; done

Dernière modification par Watael (Le 14/09/2016, à 18:41)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 14/09/2016, à 15:01

grigouille

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Watael a écrit :

modifier l'IFS, mais que c'est laid ! en plus, tu ne le restaure même pas !
et les guillemets autour des variables !?

- tu restaures.
- Une remarque pertinente de ta part aurait été de dire que la ligne 1 de mon script test.sh n'est pas correct.

- IFS n'est pas changé dans le shell père :

$ echo "$IFS\c" | od -c
0000000      \t  \n   \   c  \n
0000006
$ ./test.sh 
a b.txt
test.sh
$ echo "$IFS\c" | od -c
0000000      \t  \n   \   c  \n
0000006
$

Pour la restauration de l'IFS dans le shell enfant, je le laisse en exercice.

- Pourquoi mettre les guillemets autour de la variable f de mon exemple ? f ne sera jamais vide. Si il y a un cas qui génère un problème, je suis preneur d'explication.

- Nous avons proposé à abach plusieurs méthodes. À lui de faire son choix.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#7 Le 14/09/2016, à 18:55

Watael

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

il existe des best practices*, et parcourir la sortie d'une substitution de commande avec une boucle for (même en modifiant l'IFS) n'en fait pas partie.

*tu ne les suis pas, c'est ton problème; mais ne les défend pas comme si c'était de bonnes solutions.

tu continueras tout seul. <-point


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#8 Le 22/09/2016, à 22:03

abach

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Je reviens sur ce sujet.
J'ai réussi à faire une fonction que j'appelle dans un find. La fonction, la voici :

function rpl
{
	a=`echo $0 | tr "[:blank:]" "_"`
	if [ "$0" != "$a" ];
	then	
		# echo "$0 - $b"
		mv "$0" "$a" >/dev/null 2>&1	
	fi
}

Elle fonctionne parfaitement mais je voudrai l'étendre pour supprimer les caractère accentués et les trucs genre "ç". Je suis persuadé qu'en ajoutant quelque chose dans le tr, ça devrait marcher, ou alors en faisant des tr supplémentaires.
J'ai cherché pas mal de temps, fait un tas d'essais mais là, je sèche...


Les chiens vous regardent tous avec vénération. Les chats vous toisent tous avec dédain. Il n’y a que les cochons qui vous considèrent comme leurs égaux. - Winston Churchill
Je suis parrain Linux

Hors ligne

#9 Le 24/09/2016, à 10:33

Ferod

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Salut

http://www.commentcamarche.net/forum/af … s-accentue
Tu peux rajouter un tr 'àçéèëêïîöôùüûÀÇÉÈËÊÏÎÖÔÙÜÛ' 'aceeeeiioouuuACEEEEIIOOUUU' dans ta ligne a=...

a=`echo $0 | tr "[:blank:]" "_" | tr 'àçéèëêïîöôùüûÀÇÉÈËÊÏÎÖÔÙÜÛ' 'aceeeeiioouuuACEEEEIIOOUUU'`

j'ai pas testé mais ça doit marcher.


"When I was in the military, they gave me a medal for killing
two men, and a descharge for loving one !" Leonard Matlovich

Hors ligne

#10 Le 24/09/2016, à 12:25

abach

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Merci Ferod,

Au final, j'ai réussi à modifier ma fonction. Elle est la suivante :

function rpl
{	
	newfile=`echo $0 | sed -e "y/\/ÀÂÄâäàÊËÈÉéèêëÎÏîïÔÖôöÛÜûüùŶŸŷÿ/\/AAAaaaEEEEeeeeIIiiOOooUUuuuYYyy/; s/[ \t]/_/g; s/[^\/0-9a-zA-Z_.-]//g"`
	if [ "$0" != "$newfile" ]; then
		echo "-$0-$newfile-"
		sleep 1
		mv "$0" "$newfile"
	fi
}

Je supprime ainsi tous les caractères qui ne passent pas (sauf si j'en ai oublié) en une ligne et un "sed". Je vais noter le pb résolu.

Encore merci à tous pour votre aide.


Les chiens vous regardent tous avec vénération. Les chats vous toisent tous avec dédain. Il n’y a que les cochons qui vous considèrent comme leurs égaux. - Winston Churchill
Je suis parrain Linux

Hors ligne

#11 Le 24/09/2016, à 12:36

pingouinux

Re : [Résolu] Espaces dans des noms de dossiers et de fichiers

Pour être averti si "$newfile" existe déjà, je te conseille de remplacer

mv "$0" "$newfile"

par

mv -i "$0" "$newfile"

Tu peux en effet avoir des fichiers de noms différents qui prennent le même nom après transformation (âbc et äbc, par exemple).

Hors ligne