#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)
αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr
Hors 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
αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr
Hors 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 :
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.
αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr
Hors 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)
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 :
#É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.
LinuxMint Vera Cinnamon et d'autres machines en MATE, XFCE... 20.x , 21.x ou 19.x
Tour : Asus F2A55 / AMD A8-5600K APU 3,6GHz / RAM 16Go / Nvidia GeForce GT610 / LM21.1 Cinnamon
Portable : LDLC Mercure MH : Celeron N3450 /RAM 4Go / Intel HD graphics 500 i915 / biboot Win 10 (sur SSD) - LM21.1 MATE (sur HDD)
Hors ligne
#11 Le 06/09/2013, à 14:18
- αjet
Re : cp de certains fichiers dans plusieurs sous dossiers
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 **.
Dernière modification par alex63 (Le 06/09/2013, à 14:19)
αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr
Hors ligne
#12 Le 09/09/2013, à 15:03
- thim
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"
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].
αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr
Hors ligne