Bash um forro:copiar template_*.txt para foo_*.txt?
-
09-06-2019 - |
Pergunta
Digamos que eu tenha três arquivos (template_*.txt):
- modelo_x.txt
- modelo_y.txt
- modelo_z.txt
Quero copiá-los para três novos arquivos (foo_*.txt).
- foo_x.txt
- foo_y.txt
- foo_z.txt
Existe alguma maneira simples de fazer isso com um comando, por exemplo.
cp --enableAwesomeness template_*.txt foo_*.txt
Solução
for f in template_*.txt; do cp $f foo_${f#template_}; done
Outras dicas
[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
Minha maneira preferida:
for f in template_*.txt
do
cp $f ${f/template/foo}
done
A maneira "não me lembro da sintaxe de substituição":
for i in x y z
do
cp template_$i foo_$
done
Isso deve 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
Provavelmente quebra se seus nomes de arquivos contiverem caracteres estranhos.Remova o '-v' quando (se) você tiver certeza de que ele funciona de maneira confiável.
O comando mmv
(disponível em Debian ou Fink ou fácil de compilar) foi criado justamente para esta tarefa.Com a solução Bash simples, sempre tenho que consultar a documentação sobre expansão de variáveis.Mas mmv
é muito mais simples de usar, quase "incrível"!;-)
Seu exemplo seria:
mcp "template_*.txt" "foo_#1.txt"
mmv
também pode lidar com padrões mais complexos e possui algumas verificações de integridade, por exemplo, garantirá que nenhum dos arquivos no conjunto de destino apareça no conjunto de origem (para que você não possa sobrescrever arquivos acidentalmente).
Não sei de nada no bash ou no cp, mas existem maneiras simples de fazer esse tipo de coisa usando (por exemplo) um script perl:
($op = shift) || die "Usage: rename perlexpr [filenames]\n";
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}
Então:
rename s/template/foo/ *.txt
Mais uma maneira de fazer isso:
$ ls template_*.txt | sed -e 's/^template\(.*\)$/cp template\1 foo\1/' | ksh -sx
Sempre fiquei impressionado com o ImageMagick converter programa que faz o que você espera com formatos de imagem:
$ convert rose.jpg rose.png
Possui um programa irmão que permite conversões em lote:
$ mogrify -format png *.jpg
Obviamente, eles estão limitados a conversões de imagens, mas possuem interfaces de linha de comando interessantes.