comment renommer des fichiers lors de la copie?


12

Comment copier (style d'archivage où la date n'est pas modifiée) tous les fichiers d'un répertoire de sauvegarde dans le répertoire de l'utilisateur tout en renommant chaque fichier pour supprimer la partie chaîne aléatoire du nom (c'est-à-dire -2b0fd460_1426b77b1ee_-7b8e)?

cp de:

/backup/path/data/Erp.2014.02.16_16.57.03-2b0fd460_1426b77b1ee_-7b8e.etf

à:

/home/user/data/Erp.2014.02.16_16.57.03.etf

Chaque fichier commencera toujours par "Erp". suivi de la chaîne d'horodatage date-heure suivie de la chaîne aléatoire puis de l'extension ".etf". Je souhaite conserver tous les éléments de nom, y compris le cachet date-heure. Je veux juste supprimer la chaîne aléatoire.

La chaîne aléatoire permet plusieurs sauvegardes du même fichier. Cependant, dans ce cas, je viens d'exécuter fdupes et il n'y a pas de doublons. Je peux donc simplement restaurer tous les fichiers, en supprimant la chaîne aléatoire.

Je recherche une commande bash sur une ligne pour le faire.

Si cela ne fonctionne pas, je pourrais le faire en deux ou plusieurs étapes. J'utilise normalement KRename, mais dans ce cas, je dois le faire en bash. (Je travaille à distance.)

Réponses:


7

paxpeut faire tout cela à la fois. Vous pourriez faire:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data

paxpréserve les heures par défaut, mais peut ajouter -pepour tout conserver (mieux fait en tant que root) ou -pppour conserver les autorisations, par exemple:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data

Sinon ( paxn'est généralement pas disponible par défaut), il est sûrement préférable de faire une copie puis un rename:

cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf

De cette façon, il n'y a pas de processus différent démarré pour chaque fichier.


1
Je peux voir que je dois me familiariser avec pax. Cela ressemble à un outil très utile. Me fait me demander pourquoi ce n'est pas standard dans plus de distributions ...
MountainX

@MountainX, bonne question, selon Wikipedia, paxest dans la base standard de Linux depuis 2005. De plus, l'alternative serait GNU cpio, est probablement l'outil GNU le moins fonctionnel qui existe.
Graeme

1
+1 pour votre dernière solution et De cette façon, il n'y a pas de processus différent démarré pour chaque fichier. Mais rename c'est différent sur Fedora / Red Hat: je ne sais pas comment l'utiliser dans ce cas.
erik

15

Vous pouvez utiliser la cpcommande avec l' -aoption

-a, --archive
       same as -dR --preserve=all

Et puis utilisez une boucle for pour renommer tous les fichiers tout en les copiant:

for file in Erp*etf; do
  cp -a $file destinationDirectory/${file%%-*}.etf
done

Prêt. Démarrez cette commande dans le répertoire source.

Explication: Le %%-*va couper tous les caractères après la première occurrence d'un trait d'union / moins -et le .etfà la fin ajoute à nouveau l'extension de fichier.

Eh bien, et en tant que doublure, mettez le tout sur une seule ligne. :-) Comme ça

for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done

1
Merci, pourriez-vous s'il vous plaît citer la documentation de l' %%-*astuce? Je suis curieux.
soyuka

3

Dans zsh, utilisez zmv. Mettez ceci dans votre .zshrc:

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

Ensuite, utilisez

zcp '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

En bash:

zsh -c 'autoload zmv; zmv -C $0 $1' '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

Si vous n'avez pas zsh, une manière POSIX utilise pax (cela copie les répertoires de manière récursive).

Si vous êtes sur un système restreint sans zsh et sans pax, vous pouvez utiliser une boucle:

for source in /backup/path/data/*-*.etf; do
  basename=${source##*/}
  cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
done

1

cpn'a pas cette capacité. Je me souviens cpioavoir pu le faire, mais la page de manuel actuelle dit le contraire. Cependant, (gnu) tara une --transformoption:

 --transform, --xform EXPRESSION
       use sed replace EXPRESSION to transform file names

Vous auriez donc une ligne de commande comme:

(cd /backup/path/data; tar --create --transform 's/-.*-....//' .) | (cd /home/user/data; tar --extract)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.