com zsh
:
autoload zmv
zmv -n '*(???).*' '$1_$f'
Remova -n
quando estiver feliz.
Eu tenho um monte de arquivos em um diretório unix que se parece com o seguinte:
filename_1234567.txt
Eu preciso renomeá-los copiando os três últimos caracteres de cada nome de arquivo para a frente do nome do arquivo assim:
567_filename_1234567.txt
NOTA: A extensão e o nome do arquivo são variáveis.
Estou executando isso em uma caixa do Solaris.
com zsh
:
autoload zmv
zmv -n '*(???).*' '$1_$f'
Remova -n
quando estiver feliz.
Então você deseja preceder os três últimos caracteres do nome da base do arquivo, seguidos por um sublinhado, na frente do nome do arquivo?
#!/bin/bash
EXT=.txt
for file in *${EXT}; do # presuming all the filenames have no spaces
base=${file%${EXT}}
prefix=${base:(-3)}
newname=${prefix}_${base}${EXT}
mv ${file} ${newname}
done
Isso não funcionará no shell Korn, pois os truques usados são bash
-specific:
ksh[3]: prefix=${base:(-3)}: bad substitution
Eu gosto de fazer algo assim:
#!/bin/sh
for i in filename_*.txt; do echo "$i"; done |
sed "s/filename_\([0-9]*\)\([0-9]\{3\}\)\.txt/mv -i 'filename_.txt' '_filename_.txt'/g"
Isto imprime a lista de comandos mv
para realizar a tarefa. Se ele imprimir os comandos corretos, basta anexar | sh
no final do comando sed para fazer com que o shell os execute.
Este script usa o comando sed
subsitute s
e o recurso de referência anterior para usar partes da expressão regular correspondente na sequência de substituição.
s/regex/replacement/
As partes do padrão de expressão regular entre \(
e \)
podem ser referenciadas na sequência de substituição por \N
, em que in é um número.
Você está no Solaris, então você terá perl
. Você pode até ter rename
(ou possivelmente prename
):
rename -n 's/^(.*)(.{3})(\.[^.]*)$/$2_$1$2$3/' *.*
Remova -n
ou altere para -v
quando estiver pronto para rolar.
Pure awk
solution: a ideia básica é extrair os últimos 3 caracteres do nome base, o que significa um formulário de substring length - 6
(6 porque precisa considerar a extensão .txt
) para length - 3
. Aqui, eu apenas extraio essa substring para o VAR primeiro e, em seguida, crie o comando complete com mv
e dois nomes de arquivos a serem executados; finalmente peço a função system
para executar o comando.
Código:
awk 'BEGIN{
VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3));
CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]);
print CMD;
system(CMD);
close(CMD)
}' filename_1234567.txt
Demo:
$ awk 'BEGIN{VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3)); CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]); print CMD; system(CMD); close(CMD)}' filename_1234567.txt
mv filename_1234567.txt 567_filename_1234567.txt
$ ls filename_1234567.txt
ls: cannot access filename_1234567.txt: No such file or directory
$ ls 567_filename_1234567.txt
567_filename_1234567.txt
$