Bash One Liner :copier template_*.txt dans foo_*.txt ?
-
09-06-2019 - |
Question
Disons que j'ai trois fichiers (template_*.txt) :
- modèle_x.txt
- modèle_y.txt
- modèle_z.txt
Je souhaite les copier dans trois nouveaux fichiers (foo_*.txt).
- foo_x.txt
- foo_y.txt
- foo_z.txt
Existe-t-il un moyen simple de le faire avec une seule commande, par ex.
cp --enableAwesomeness template_*.txt foo_*.txt
La solution
for f in template_*.txt; do cp $f foo_${f#template_}; done
Autres conseils
[01:22 PM] matt@Lunchbox:~/tmp/ba$
ls
template_x.txt template_y.txt template_z.txt
[01:22 PM] matt@Lunchbox:~/tmp/ba$
for i in template_*.txt ; do mv $i foo${i:8}; done
[01:22 PM] matt@Lunchbox:~/tmp/ba$
ls
foo_x.txt foo_y.txt foo_z.txt
Ma méthode préférée :
for f in template_*.txt
do
cp $f ${f/template/foo}
done
La méthode "Je ne me souviens pas de la syntaxe de substitution":
for i in x y z
do
cp template_$i foo_$
done
Cela devrait fonctionner :
for file in template_*.txt ; do cp $file `echo $file | sed 's/template_\(.*\)/foo_\1/'` ; done
for i in template_*.txt; do cp -v "$i" "`echo $i | sed 's%^template_%foo_%'`"; done
Cela se casse probablement si vos noms de fichiers contiennent des caractères géniaux.Supprimez le «-v» lorsque (si) vous êtes sûr qu'il fonctionne de manière fiable.
La commande mmv
(disponible en Debian ou Mouchard ou facile à compiler soi-même) a été créé précisément pour cette tâche.Avec la solution plain Bash, je dois toujours consulter la documentation sur l'expansion des variables.Mais mmv
est beaucoup plus simple à utiliser, assez proche du "génial" !;-)
Votre exemple serait :
mcp "template_*.txt" "foo_#1.txt"
mmv
peut également gérer des modèles plus complexes et comporte quelques contrôles de cohérence, par exemple, il garantira qu'aucun des fichiers de l'ensemble de destination n'apparaît dans l'ensemble source (vous ne pouvez donc pas écraser accidentellement les fichiers).
Je ne connais rien en bash ou sur cp, mais il existe des moyens simples de faire ce genre de chose en utilisant (par exemple) un script Perl :
($op = shift) || die "Usage: rename perlexpr [filenames]\n";
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}
Alors:
rename s/template/foo/ *.txt
Encore une autre façon de procéder :
$ ls template_*.txt | sed -e 's/^template\(.*\)$/cp template\1 foo\1/' | ksh -sx
J'ai toujours été impressionné par ImageMagick convertir programme qui fait ce que vous attendez avec les formats d'image :
$ convert rose.jpg rose.png
Il possède un programme frère qui permet les conversions par lots :
$ mogrify -format png *.jpg
Celles-ci se limitent évidemment aux conversions d’images, mais elles disposent d’interfaces de ligne de commande intéressantes.