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 27/01/2017, à 18:27

DonutMan75

[RESOLU] [bash] cp non destructif avec --backup

Bonjour à tous,
ce post est lié à un fil que j'ai initié ici et qui portait sur la copie automatique des photos d'un répertoire.

Je souhaiterais affiner les options de cp pour copier *à plat* un ensemble de fichiers jpg d'un répertoire A (avec ses sous-répertoires) vers un répertoire B, en gérant proprement les éventuels noms de fichiers dupliqués.

Clairement dit, faire en sorte que
./A/dossier1/toto.jpg
./A/dossier2/toto.jpg
etc. etc.

apparaissent dans B sous la forme :
./B/toto.jpg
./B/toto_1.jpg
./B/toto_2.jpg
etc. etc.

Ce que j'ai trouvé de mieux jusqu'à présent c'est :

$ find ./A/ -name *jpg -exec cp --backup='numbered' {} ./B/ \;

A l'issue de cette commande, B est peuplé des fichiers :
./B/toto.jpg
./B/toto.jpg.~1~
./B/toto.jpg.~2~
etc. etc.

L'option --suffix='_' n'a chez moi aucune incidence lorsqu'utilisée avec --backup='numbered'.

Avant de me tourner vers des solutions plus compliqués (à base de boucle for en shell script), je voulais sonder la communauté pour savoir si vous aviez déjà rencontré ce problème.. Peut-être s'agit t'il d'une limitation de cp ?

En gros, cp gère le backup de deux façons :

  1. Si la cible existe, alors on la duplique en rajoutant _SUFFIXE à la fin et ensuite on écrase le fichier cible. Ici l'option --suffix est correctement prise en compte mais le soucis c'est que si on a plusieurs fichiers dupliqués on écrasera autant de fois le fichier suffixé... C'est l'option --backup='simple'

  2. Si la cible existe, alors on la duplique en rajoutant .~k~ à la fin du fichier avec k un nombre incrémental. Mais dans ce cas, on perd notre possibilité de contôle du format de sortie, ce sera du .~k~ de toute façon. Il s'agit ici de l'option --backup='numbered'

Qu'en dites-vous ?

Merci d'avance pour vos avis éclairés smile

Donut.

Dernière modification par DonutMan75 (Le 30/01/2017, à 12:17)

Hors ligne

#2 Le 27/01/2017, à 20:20

MicP

Re : [RESOLU] [bash] cp non destructif avec --backup

Bonsoir

EDIT : Modifié suite au conseil de Watael dans son message #4

Au cas où tu utiliserais :

find ./A/ -name *jpg -exec cp --backup='numbered' {} ./B/ \;

Tu pourrais lancer juste après :

mareg='(.*).jpg.~(.*)~';for nomFich in *;do [[ "${nomFich}" =~ ${mareg} ]] && mv "${nomFich}" "${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.jpg";done
michel@debg53sw:~/aef$ ls -1
pasToucherÀça.txt
toto espacée.jpg.~124~
toto espace.jpg.~1~
toto espace.jpg.~2~
toto.jpg.~1~
toto.jpg.~2~
michel@debg53sw:~/aef$ mareg='(.*).jpg.~(.*)~';for nomFich in *;do [[ "${nomFich}" =~ ${mareg} ]] && mv "${nomFich}" "${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.jpg";done
michel@debg53sw:~/aef$ ls -1
pasToucherÀça.txt
toto_1.jpg
toto_2.jpg
toto espace_1.jpg
toto espace_2.jpg
toto espacée_124.jpg
michel@debg53sw:~/aef$ 

En fait, c'est que du bash

Dernière modification par MicP (Le 29/01/2017, à 05:45)

Hors ligne

#3 Le 27/01/2017, à 22:16

DonutMan75

Re : [RESOLU] [bash] cp non destructif avec --backup

Bonsoir MicP,
merci pour cette solution !

En fait, je me mélange un peu les pinceaux entre les différents bash...
Pourrais-tu me dire à quoi servent les parenthèses pour ta commande ? C'est à dire: (IFS=... ... ; done)

Par ailleurs, le match de la regex tu la fait avec "[[ $VAR =~ $REGEXP ]]" il me semble. Ca aussi je ne connaissais pas, c'est une subtilité du bash ? De mon côté j'avais l'habitude de faire un "if $(grep -E $REGEXP $VAR)" mais ta façon de faire est beaucoup plus simple !

Enfin, j'aurais la même question concernant tes BASH_REMATCH[1] et BASH_REMATCH[2], c'est l'équivalent de \1 et \2 de sed je suppose ?

Merci beaucoup pour ta réponse en tout cas wink

Donut.

Hors ligne

#4 Le 27/01/2017, à 22:20

Watael

Re : [RESOLU] [bash] cp non destructif avec --backup

for nomFich in $(ls)

non, mais ça va pas !? même en modifiant l'IFS.

for f in *

épissétou !

for fic in $(ls)...n'importe quoi.

wink

Dernière modification par Watael (Le 27/01/2017, à 22:22)


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

Hors ligne

#5 Le 27/01/2017, à 22:44

MicP

Re : [RESOLU] [bash] cp non destructif avec --backup

…à quoi servent les parenthèses…

La mise entre parenthèses me permet de faire exécuter la ligne de commande dans un sous-shell,
de cette façon, la variable IFS de l'environnement du shell original ne sera pas modifiée.

Mais ça ne sera pas nécessaire, car en utilisant le motifs générique * à la place de $(ls) (voir message #4 de Watael), le problème est résolu => pas besoin de modifier la variable IFS

=======

…le match de la regex tu la fait avec "[[ $VAR =~ $REGEXP ]]" il me semble. Ca aussi je ne connaissais pas, c'est une subtilité du bash ?…

Oui.

=======

…même question concernant tes BASH_REMATCH[1] et BASH_REMATCH[2],…

Entre la ligne de commande :

man bash

c'est le pager less qui affiche les pages man, et en visualisant la page man d'une commande,
si tu tape sur la touche h, la page d'aide en ligne de less sera affichée.
En tapant sur la touche q, tu te retrouvera dans la page man du bash.

Avec le pager less, il est possible d'utiliser un motif de recherche (la page man de bash est assez longue)
Je t'invite donc, quand tu visualise la page man de bash, à taper sur la touche /
et à entrer 4 caractères espace suivis du motif de recherche : BASH_REMATCH

En tapant sur la touche n, tu trouvera l'occurrence suivante,
et avec la touche N, l’occurrence précédente.

=======
Pour un meilleur confort de lecture des pages man,
je te recommande d'ajouter l'extrait ci-dessous à la fin de ton fichier ~/.bashrc


EDIT : Voir les deux messages qui suivent

et ne pas tenir compte de l'extrait suivant.

# Colored man pages
man() {
      env                                     \
      LESS_TERMCAP_mb=$(printf "\e[1;31m")    \
      LESS_TERMCAP_md=$(printf "\e[1;31m")    \
      LESS_TERMCAP_me=$(printf "\e[0m")       \
      LESS_TERMCAP_se=$(printf "\e[0m")       \
      LESS_TERMCAP_so=$(printf "\e[1;44;33m") \
      LESS_TERMCAP_ue=$(printf "\e[0m")       \
      LESS_TERMCAP_us=$(printf "\e[1;32m")    \
      man "$@"
}

Ces variables d'environnement, seront prises en compte à la prochaine ouverture d'une fenêtre d'émulateur de terminal.

=======
Je précise que je ne suis pas programmeur,
il y a des personnes beaucoup plus compétentes qui auraient sans doute trouvé une solution plus élégante, et certainement plus efficace.

Dernière modification par MicP (Le 29/01/2017, à 06:57)

Hors ligne

#6 Le 27/01/2017, à 23:09

Watael

Re : [RESOLU] [bash] cp non destructif avec --backup

c'est bizarre de créer une fonction quand un simple export de variables suffirait.
et les printf sont inutiles :

export LESS_TERMCAP_mb=$'\E[01;31m'

par exemple.

de plus, j'aurais donné le chemin complet de la commande man pour que ce ne soit pas la fonction qui soit appelée


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

Hors ligne

#7 Le 28/01/2017, à 00:10

MicP

Re : [RESOLU] [bash] cp non destructif avec --backup

Je n'avais pas osé modifier le comportement général de less
Pour le chemin complet, comme il s'agit du bash utilisateur, je pensais que le PATH suffirait.

Mais je vais changer ça : c'est sans doute une habitude à prendre que je n'ai pas encore prise, et pour les printf aussi. (faudra que je fasse gaffe à différencier la commande printf et la primitive printf du bash)

# less en couleurs
#  voir :
#    man termcap
#    man console_codes
export                         \
LESS_TERMCAP_mb=$'\e[1;31m'    \
LESS_TERMCAP_md=$'\e[1;31m'    \
LESS_TERMCAP_me=$'\e[0m'       \
LESS_TERMCAP_se=$'\e[0m'       \
LESS_TERMCAP_so=$'\e[1;44;33m' \
LESS_TERMCAP_ue=$'\e[0m'       \
LESS_TERMCAP_us=$'\e[1;32m'

Il y a plus de dix ans que j'avais trouvé l'extrait que j'ai cité dans mon message précédent, et comme il ne m'avait jamais posé de problèmes, je l'avais laissé tel quel.

Merci beaucoup pour les conseils.

Dernière modification par MicP (Le 29/01/2017, à 06:52)

Hors ligne

#8 Le 28/01/2017, à 12:02

Hizoka

Re : [RESOLU] [bash] cp non destructif avec --backup

Merci à vous pour ces informations toujours pratiques smile
ça permet de faire des rappels intéressants.


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#9 Le 29/01/2017, à 05:40

MicP

Re : [RESOLU] [bash] cp non destructif avec --backup

@Watael

j'avais oublié de supprimer le $(ls) et le IFS mais je fais ça de suite.

Pour ma défense, j'étais défoncé. (médocs, mais ça va mieux maintenant)
du coup, j'avais zappé ton message #4

Dernière modification par MicP (Le 29/01/2017, à 06:06)

Hors ligne

#10 Le 30/01/2017, à 12:17

DonutMan75

Re : [RESOLU] [bash] cp non destructif avec --backup

Bonjour à tous,
merci pour vos commentaires, ça permet de faire le lien entre pleins de trucs !!
J'avais jamais réalisé que man <commande> faisait appel à less smile

Bonne journée smile

Donut.

Hors ligne

#11 Le 30/01/2017, à 13:42

MicP

Re : [RESOLU] [bash] cp non destructif avec --backup

Tu as aussi la commande mail qui utilise less pour visualiser le contenu des mails,
et beaucoup d'autres programmes utilisent aussi ce pager qui est le successeur du pager more

C'est donc un très bon investissement d'apprendre à utiliser les raccourcis clavier et fonctionnalités de la commande less
d'autant que ces mêmes raccourcis sont aussi utilisés par d'autres programmes (comme par exemple vim) .

Dernière modification par MicP (Le 30/01/2017, à 13:44)

Hors ligne