tutorial - Bash One Liner: copia la plantilla_*. Txt a foo_*. Txt?
sed manual (8)
Supongamos que tengo tres archivos (plantilla _ *. Txt):
- template_x.txt
- template_y.txt
- template_z.txt
Quiero copiarlos en tres archivos nuevos (foo _ *. Txt).
- foo_x.txt
- foo_y.txt
- foo_z.txt
¿Hay alguna manera simple de hacer eso con un comando, por ejemplo,
cp --enableAwesomeness template_*.txt foo_*.txt
El comando mmv
(disponible en Debian o Fink o fácil de compilar) se creó precisamente para esta tarea. Con la solución sencilla de Bash, siempre tengo que buscar la documentación sobre la expansión variable. ¡Pero mmv
es mucho más fácil de usar, muy mmv
a "genialidad"! ;-)
Tu ejemplo sería:
mcp "template_*.txt" "foo_#1.txt"
mmv
puede manejar patrones más complejos también y tiene algunas verificaciones de cordura, por ejemplo, se asegurará de que ninguno de los archivos en el conjunto de destino aparezca en el conjunto de origen (para que no pueda sobrescribir accidentalmente los archivos).
Esto debería funcionar:
for file in template_*.txt ; do cp $file `echo $file | sed ''s/template_/(.*/)/foo_/1/''` ; done
No sé nada en bash o en cp, pero hay formas simples de hacer este tipo de cosas usando (por ejemplo) un script de Perl:
($op = shift) || die "Usage: rename perlexpr [filenames]/n";
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}
Entonces:
rename s/template/foo/ *.txt
for i in template_*.txt; do cp -v "$i" "`echo $i | sed ''s%^template_%foo_%''`"; done
Probablemente se rompa si sus nombres de archivo tienen caracteres funky en ellos. Elimine el ''-v'' cuando (si) obtiene la confianza de que funciona de manera confiable.
[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
Otra forma de hacerlo:
$ ls template_*.txt | sed -e ''s/^template/(.*/)$/cp template/1 foo/1/'' | ksh -sx
Siempre me ha impresionado el programa ImageMagick convert que hace lo que espera con formatos de imagen:
$ convert rose.jpg rose.png
Tiene un programa hermano que permite conversiones por lotes:
$ mogrify -format png *.jpg
Obviamente, estos están limitados a las conversiones de imagen, pero tienen interfaces de línea de comando interesantes.
for f in template_*.txt; do cp $f foo_${f#template_}; done
Mi forma preferida:
for f in template_*.txt
do
cp $f ${f/template/foo}
done
La forma "No-recuerdo-la-sustitución-sintaxis":
for i in x y z
do
cp template_$i foo_$
done