Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

#1 Le 05/09/2013, à 15:19

thim

cp de certains fichiers dans plusieurs sous dossiers

Bonjour,

Voila je n'arrive pas a faire un script :
J'ai un dossier, plusieurs sous-dossiers (dont le nom peut varier) et des fichiers à l’intérieur.

Je dois copier tous les fichiers "dossier/sous-dossier/*.ext" vers une cible qui me reprend les mêmes noms de sous-dossiers...

J'ai essayé un "cp -R dossier/*/*.ext dossier2/*/" mais ça ne marche pas...
Auriez vous une piste à me donner s'il vous plait?

Merci
thim

Dernière modification par thim (Le 05/09/2013, à 15:21)

Hors ligne

#2 Le 05/09/2013, à 15:37

αjet

Re : cp de certains fichiers dans plusieurs sous dossiers

J'ai un script qui fait a peu pres la meme chose. Je le poste ce soir.
Tu peux aussi regarder ce post: http://forum.ubuntu-fr.org/viewtopic.php?id=1363051

Dernière modification par alex63 (Le 05/09/2013, à 15:39)


a.k.a. alex63

En ligne

#3 Le 05/09/2013, à 16:18

thim

Re : cp de certains fichiers dans plusieurs sous dossiers

ok je regarde ça!
merci

Hors ligne

#4 Le 05/09/2013, à 20:53

αjet

Re : cp de certains fichiers dans plusieurs sous dossiers

Comme promis voici le script en question. C'est le script que j'utilise pour exporter et redimensioner mes photos. Le point commun avec ce que tu souhaite faire est que je reproduis l'arborescence de dossiers.

#!/bin/bash
######
# Function: export resized photos from main library to an export folder. Target folder structure is identical to the source library. 
# Requirements:
#  * ImageMagick  for resize operation
#  * exiv2 (http://www.exiv2.org/) for reading picture exif
######


base_src_folder="~/Pictures/Photos/0.Original/2013"
base_dest_folder="~/Pictures/Photos/1.Exports/1.MR/2013"
cammodel="NIKON D800";
pic_size=1500x1500;

#find command outputs the absolute path (folders & filename).
find "$base_src_folder" -regextype posix-extended  -iregex '.*/AEF_[0-9]{4}.jpg' | while read line 
do
	
	bname=$(basename "$line");  #Source Filename, without folder name
	f=${line:${#base_src_folder}+1}; #f = Base name - base source folder
	if [ "$f" == "$bname" ]; then
		f="";  #When files are in the root folder
	else
		f=${f:0:${#f}-${#bname}-1}; 
	fi
	
	curcam=$(exiv2 -q "$line" | grep 'Camera model' | sed -r 's/^.*:\s+//'); # Reading exif and extracting camera model. 

	# Pictures are exported and resized only if taken by this camera model.
	if [ "$curcam" == "$cammodel" ]; then
		if [ -z $f ]; then # Check if subfolder f is empty.
			dest_folder="$base_dest_folder";
		else
			dest_folder="$base_dest_folder/$f";
		fi
		
		# Check if picture has olready been previously exported. If so, we don't redo it!
		if [ ! -f "$dest_folder/$bname" ]; then
			if [ ! -d "$dest_folder" ]; then # If destination folder doesn't' exist, we create it. 
				mkdir -p "$dest_folder";
			fi 	
			echo "$( date +%H:%M:%S ) - Processing '$bname'..."; # Logging like a boss :P
			convert "$line" -resize $pic_size "$dest_folder/$bname" # Photo resize with ImageMagick 
		fi
	fi
done

Peut etre (non teste), que ce script pourrait repondre a tes attentes:

#!/bin/bash
######
# Function: export resized photos from main library to an export folder. Target folder structure is identical to the source library. 
# Requirements:
#  * ImageMagick  for resize operation
#  * exiv2 (http://www.exiv2.org/) for reading picture exif
######


base_src_folder="~/Pictures/Photos/0.Original/2013"
base_dest_folder="~/Pictures/Photos/1.Exports/1.MR/2013"

#find command outputs the absolute path (folders & filename).
find "$base_src_folder" -regextype posix-extended  -iregex '.*/.ext' | while read line 
do
	
	bname=$(basename "$line");  #Source Filename, without folder name
	f=${line:${#base_src_folder}+1}; #f = Base name - base source folder
	if [ "$f" == "$bname" ]; then
		f="";  #When files are in the root folder
	else
		f=${f:0:${#f}-${#bname}-1}; 
	fi
	

		if [ -z $f ]; then # Check if subfolder f is empty.
			dest_folder="$base_dest_folder";
		else
			dest_folder="$base_dest_folder/$f";
		fi
		
		# Check if picture has olready been previously exported. If so, we don't redo it!
		if [ ! -f "$dest_folder/$bname" ]; then
			if [ ! -d "$dest_folder" ]; then # If destination folder doesn't' exist, we create it. 
				mkdir -p "$dest_folder";
			fi 	
			echo "$( date +%H:%M:%S ) - Copying '$bname'..."; # Logging like a boss :P
			cp "$line"  "$dest_folder/$bname" # Copying file to its destination folder 
		fi
done

a.k.a. alex63

En ligne

#5 Le 05/09/2013, à 22:00

ytreza

Re : cp de certains fichiers dans plusieurs sous dossiers

Bonsoir !
Pardon si ma question parait indélicate, Thim, mais pourquoi ne pas utiliser une commande de synchronisation, comme "rsync" par exemple, qui est éprouvée et optimisée depuis plusieurs années, plutôt que de s’embêter à créer un script qui sera, au final, certainement moins performant (le script shell est loin d'être une référence en termes de performances...) ?

Hors ligne

#6 Le 05/09/2013, à 23:24

ytreza

Re : cp de certains fichiers dans plusieurs sous dossiers

Bon, l'idée m'a trottée dans la tête tout à l'heure, et je pense avoir ce que tu recherches tongue :

repOri='/repertoire/a/analyser'
repCopie='/repertoire/destination/des/copies'
modele='*.ext'

for fichier in $(find "$repOri" -name "$modele" -type f) ; do mv "$fichier" "$repCopie${fichier:${#repOri}}"; done

Dernière modification par ytreza (Le 05/09/2013, à 23:25)

Hors ligne

#7 Le 05/09/2013, à 23:51

αjet

Re : cp de certains fichiers dans plusieurs sous dossiers

ytreza, bonne idee, mais:
*  Il faudrait remplacer mv par cp.
* S'il manque des dossiers dans repertoire de destination, il faut le creer au prealable sinon impossible de deplacer ou copier les fichiers.


a.k.a. alex63

En ligne

#8 Le 05/09/2013, à 23:51

Postmortem

Re : cp de certains fichiers dans plusieurs sous dossiers

Salut,
for fichier in $(find...) n'est pas une bonne idée si les noms de fichiers contiennent des espaces.
Plutôt faire :

repOri='/repertoire/a/analyser'
repCopie='/repertoire/destination/des/copies'
modele='*.ext'

while read -rd ''
do
   rep=${REPLY%/*}
   repDest=${rep:${#repOri}}
   mkdir -p "$repCopie$repDest"
   cp "$REPLY" "$repCopie$repDest"
done < <(find "$repOri" -name "$modele" -type f -print0)

Edit : corrections suite aux remarques de alex63

Re-edit :
En bash et beaucoup plus court :

shopt -s globstar
cd "/repertoire/a/analyser"
cp --parent **/*.ext "/repertoire/destination/des/copies"

Dernière modification par Postmortem (Le 06/09/2013, à 00:23)


Trusty Tahr (64 bits), Athlon64 3800+, ATI Radeon HD4870

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#9 Le 06/09/2013, à 00:55

ytreza

Re : cp de certains fichiers dans plusieurs sous dossiers

Exact, j'ai été un peu trop vite ! J'avais oublié de redéfinir l'IFS ! J'en profite pour peaufiner, même si manifestement Postmortem a trouvé plus simple tongue :

#Éviter le problème des espaces dans les noms de fichier avec for...in...find
IFS='
'
#Parametres
repOri='/repertoire/a/analyser'
repCopie='/repertoire/destination/des/copies'
modele='*.ext'

#Recherche des fichiers finissant par .ext
for fichier in $(find "$repOri" -name "$modele" -type f)
do
    #Détermination du chemin de la cible de la copie
    $fichierCopie="$repCopie${fichier:${#repOri}}"
    #Création des répertoires parents éventuels
    $repFichierCopie=dirname "$fichierCopie"
    if [ ! -d "$repFichierCopie" ];    then mkdir -p "$repFichierCopie"; fi
    #Copie
    cp "$fichier" "$fichierCopie"
done

Dernière modification par ytreza (Le 06/09/2013, à 00:56)

Hors ligne

#10 Le 06/09/2013, à 09:14

serged

Re : cp de certains fichiers dans plusieurs sous dossiers

Avec rsync :
Voir ce fil récent dans le forum LinuxMint.


Linux-Mint Qiana 64 (Cinnamon) sur ASUS F2A55/AMD A8-5600K APU

Hors ligne

#11 Le 06/09/2013, à 14:18

αjet

Re : cp de certains fichiers dans plusieurs sous dossiers

Postmortem a écrit :

Re-edit :
En bash et beaucoup plus court :

shopt -s globstar
cd "/repertoire/a/analyser"
cp --parent **/*.ext "/repertoire/destination/des/copies"

Merci, je ne connaissais pas 'globstar'  et l'utilisation de **. smile

Dernière modification par alex63 (Le 06/09/2013, à 14:19)


a.k.a. alex63

En ligne

#12 Le 09/09/2013, à 15:03

thim

Re : cp de certains fichiers dans plusieurs sous dossiers

Postmortem a écrit :

Salut,
for fichier in $(find...) n'est pas une bonne idée si les noms de fichiers contiennent des espaces.
Plutôt faire :

repOri='/repertoire/a/analyser'
repCopie='/repertoire/destination/des/copies'
modele='*.ext'

while read -rd ''
do
   rep=${REPLY%/*}
   repDest=${rep:${#repOri}}
   mkdir -p "$repCopie$repDest"
   cp "$REPLY" "$repCopie$repDest"
done < <(find "$repOri" -name "$modele" -type f -print0)

Edit : corrections suite aux remarques de alex63

Re-edit :
En bash et beaucoup plus court :

shopt -s globstar
cd "/repertoire/a/analyser"
cp --parent **/*.ext "/repertoire/destination/des/copies"

J'ai utilisé le while.
Il marche très bien. Je vais maintenant essayer de le comprendre!!!

Merci pour tout à vous tous!

Hors ligne

#13 Le 09/09/2013, à 16:57

αjet

Re : cp de certains fichiers dans plusieurs sous dossiers

Cool, il faudrait editer le titre et mettre [Resolu]. smile


a.k.a. alex63

En ligne

Haut de page ↑