Bash One Liner:¿copiar template_*.txt a foo_*.txt?
-
09-06-2019 - |
Pregunta
Digamos que tengo tres archivos (template_*.txt):
- plantilla_x.txt
- plantilla_y.txt
- plantilla_z.txt
Quiero copiarlos en tres archivos nuevos (foo_*.txt).
- foo_x.txt
- foo_y.txt
- foo_z.txt
¿Existe alguna forma sencilla de hacerlo con un comando, p.
cp --enableAwesomeness template_*.txt foo_*.txt
Solución
for f in template_*.txt; do cp $f foo_${f#template_}; done
Otros consejos
[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
Mi forma preferida:
for f in template_*.txt
do
cp $f ${f/template/foo}
done
La forma "No recuerdo la sintaxis de sustitución":
for i in x y z
do
cp template_$i foo_$
done
Esto debería funcionar:
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
Probablemente se rompa si los nombres de sus archivos tienen caracteres originales.Elimine la '-v' cuando (si) tenga confianza en que funciona de manera confiable.
El comando mmv
(disponible en Debian o Soplón o fácil de compilar usted mismo) fue creado precisamente para esta tarea.Con la solución Bash simple, siempre tengo que buscar la documentación sobre la expansión de variables.Pero mmv
Es mucho más sencillo de usar, ¡bastante cercano a lo "genial"!;-)
Tu ejemplo sería:
mcp "template_*.txt" "foo_#1.txt"
mmv
También puede manejar patrones más complejos y tiene algunas comprobaciones de cordura, por ejemplo, se asegurará de que ninguno de los archivos del conjunto de destino aparezca en el conjunto de origen (para que no pueda sobrescribir archivos accidentalmente).
No sé nada sobre bash o cp, pero hay formas sencillas de hacer este tipo de cosas usando (por ejemplo) un script en 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
Otra forma más de hacerlo:
$ ls template_*.txt | sed -e 's/^template\(.*\)$/cp template\1 foo\1/' | ksh -sx
Siempre me ha impresionado ImageMagick convertir programa que hace lo que esperas con los formatos de imagen:
$ convert rose.jpg rose.png
Tiene un programa hermano que permite conversiones por lotes:
$ mogrify -format png *.jpg
Obviamente, estos se limitan a conversiones de imágenes, pero tienen interesantes interfaces de línea de comandos.