Com o novo bash
, você pode usar a expansão de chaves no formulário {a..z}
:
i=1; for f in file{a..z}; do mv "$f.csv" "${f%?}$((i++)).csv"; done
Estou tentando renomear arquivos nomeados na forma de splitfile[a-z]
para splitfile[1-26].csv
, ou seja, quero renomear splitfilea
para splitfile1.csv
e assim por diante.
Eu tentei o seguinte comando:
mv splitfile[a-z] splitfile[1-26].csv
mas não funciona.Melhoramente me ajude, enquanto isso eu estou tentando com loop for.
Com o novo bash
, você pode usar a expansão de chaves no formulário {a..z}
:
i=1; for f in file{a..z}; do mv "$f.csv" "${f%?}$((i++)).csv"; done
Se você tiver o perl
utility rename
(às vezes chamado de prename
), poderá usá-lo para renomear seus arquivos
rename -n 's/([a-z])$/ord($1)-96/e and $_ .= ".csv"' splitfile?
O que isto faz é pegar a última letra dos seus nomes de arquivos correspondentes a splitfile?
, converter o caractere em seu equivalente ordinal ASCII (ie a = 97, b = 98, ...), subtrair 96 e substituir a letra correspondente com o resultado. Para todos os nomes de arquivos nos quais essa substituição foi aplicada com êxito, a sequência ".csv" é anexada.
O comando acima não alterará seus arquivos reais (é o que faz o -n
flag), ele imprimirá apenas o que faria. Execute-o uma vez, verifique a saída e, se estiver correto, execute-o novamente sem o -n
.
Com zsh
, não é necessário usar um loop, apenas uma função zmv
:
autoload -U zmv
i=1 zmv -v '(file)[a-z].csv' '$1$((i++)).csv'
Ou se nem todos os file[a-z].csv
existirem:
letters=({a..z})
zmv -v '(file)([a-z]).csv' '$1$letters[(i)$2].csv'
Este script sh
renomeia corretamente os arquivos, mesmo se os arquivos estiverem faltando na sequência a-z
:
#!/bin/sh
for n in $(seq 26)
do
f=$(printf $(printf 'file\%03o.csv' $((n+96))))
[ -e $f ] && echo mv $f file$n.csv
done
Esta é uma maneira de fazer isso com um shell POSIX, supondo que todos os arquivos existam na seqüência a-z
:
#!/bin/sh
i=1
for f in file[a-z].csv
do
echo mv $f file$i.csv
i=$((i+1))
done
Outra solução bastante portátil ...
eval set "'' $(dc -e'123[1-ddP32P97<a]salax')" ### reverse-order lowercase ascii
while "${2+shift}" 2>&- ### only iterate while we should
do for f in ./*["$1"].ext ### glob* is fine - sorting's done
do [ "${f%%*\]????}" ] && ### *null glob* kind of
echo mv "$f" "${f%?.*}${?%${10+?}}$#.${f##*.}" ### echo doesn't mv much
done; done ### $? zero-pads to two decimals
Depois de fazer a linha set
acima, geramos um conjunto de testes para essa solução como ...
eval ' for A in '"$(printf %1.s%s%1.s "$@" "" ";do for a in$@")"';
do echo "$A$a" > "${A}file$a.ext"; done; done'
Que iterativamente pula cada duas letras para cada duas letras ... se isso faz sentido. Os resultados foram:
ls -m
bfilec.ext, bfilef.ext, bfilei.ext, bfilel.ext, bfileo.ext, bfiler.ext,
bfileu.ext, bfilex.ext, efilec.ext, efilef.ext, efilei.ext, efilel.ext,
efileo.ext, efiler.ext, efileu.ext, efilex.ext, hfilec.ext, hfilef.ext,
hfilei.ext, hfilel.ext, hfileo.ext, hfiler.ext, hfileu.ext, hfilex.ext,
kfilec.ext, kfilef.ext, kfilei.ext, kfilel.ext, kfileo.ext, kfiler.ext,
kfileu.ext, kfilex.ext, nfilec.ext, nfilef.ext, nfilei.ext, nfilel.ext,
nfileo.ext, nfiler.ext, nfileu.ext, nfilex.ext, qfilec.ext, qfilef.ext,
qfilei.ext, qfilel.ext, qfileo.ext, qfiler.ext, qfileu.ext, qfilex.ext,
tfilec.ext, tfilef.ext, tfilei.ext, tfilel.ext, tfileo.ext, tfiler.ext,
tfileu.ext, tfilex.ext, wfilec.ext, wfilef.ext, wfilei.ext, wfilel.ext,
wfileo.ext, wfiler.ext, wfileu.ext, wfilex.ext, zfilec.ext, zfilef.ext,
zfilei.ext, zfilel.ext, zfileo.ext, zfiler.ext, zfileu.ext, zfilex.ext
E então eu testei ...
while ...; do ...; done | { HOME=/dev/null; paste -d', ' - ~ - ~; }
mv ./bfilex.ext ./bfile24.ext, mv ./efilex.ext ./efile24.ext,
mv ./hfilex.ext ./hfile24.ext, mv ./kfilex.ext ./kfile24.ext,
mv ./nfilex.ext ./nfile24.ext, mv ./qfilex.ext ./qfile24.ext,
mv ./tfilex.ext ./tfile24.ext, mv ./wfilex.ext ./wfile24.ext,
mv ./zfilex.ext ./zfile24.ext, mv ./bfileu.ext ./bfile21.ext,
mv ./efileu.ext ./efile21.ext, mv ./hfileu.ext ./hfile21.ext,
mv ./kfileu.ext ./kfile21.ext, mv ./nfileu.ext ./nfile21.ext,
mv ./qfileu.ext ./qfile21.ext, mv ./tfileu.ext ./tfile21.ext,
mv ./wfileu.ext ./wfile21.ext, mv ./zfileu.ext ./zfile21.ext,
mv ./bfiler.ext ./bfile18.ext, mv ./efiler.ext ./efile18.ext,
mv ./hfiler.ext ./hfile18.ext, mv ./kfiler.ext ./kfile18.ext,
mv ./nfiler.ext ./nfile18.ext, mv ./qfiler.ext ./qfile18.ext,
mv ./tfiler.ext ./tfile18.ext, mv ./wfiler.ext ./wfile18.ext,
mv ./zfiler.ext ./zfile18.ext, mv ./bfileo.ext ./bfile15.ext,
mv ./efileo.ext ./efile15.ext, mv ./hfileo.ext ./hfile15.ext,
mv ./kfileo.ext ./kfile15.ext, mv ./nfileo.ext ./nfile15.ext,
mv ./qfileo.ext ./qfile15.ext, mv ./tfileo.ext ./tfile15.ext,
mv ./wfileo.ext ./wfile15.ext, mv ./zfileo.ext ./zfile15.ext,
mv ./bfilel.ext ./bfile12.ext, mv ./efilel.ext ./efile12.ext,
mv ./hfilel.ext ./hfile12.ext, mv ./kfilel.ext ./kfile12.ext,
mv ./nfilel.ext ./nfile12.ext, mv ./qfilel.ext ./qfile12.ext,
mv ./tfilel.ext ./tfile12.ext, mv ./wfilel.ext ./wfile12.ext,
mv ./zfilel.ext ./zfile12.ext, mv ./bfilei.ext ./bfile09.ext,
mv ./efilei.ext ./efile09.ext, mv ./hfilei.ext ./hfile09.ext,
mv ./kfilei.ext ./kfile09.ext, mv ./nfilei.ext ./nfile09.ext,
mv ./qfilei.ext ./qfile09.ext, mv ./tfilei.ext ./tfile09.ext,
mv ./wfilei.ext ./wfile09.ext, mv ./zfilei.ext ./zfile09.ext,
mv ./bfilef.ext ./bfile06.ext, mv ./efilef.ext ./efile06.ext,
mv ./hfilef.ext ./hfile06.ext, mv ./kfilef.ext ./kfile06.ext,
mv ./nfilef.ext ./nfile06.ext, mv ./qfilef.ext ./qfile06.ext,
mv ./tfilef.ext ./tfile06.ext, mv ./wfilef.ext ./wfile06.ext,
mv ./zfilef.ext ./zfile06.ext, mv ./bfilec.ext ./bfile03.ext,
mv ./efilec.ext ./efile03.ext, mv ./hfilec.ext ./hfile03.ext,
mv ./kfilec.ext ./kfile03.ext, mv ./nfilec.ext ./nfile03.ext,
mv ./qfilec.ext ./qfile03.ext, mv ./tfilec.ext ./tfile03.ext,
mv ./wfilec.ext ./wfile03.ext, mv ./zfilec.ext ./zfile03.ext,
Aqui está uma sugestão alternativa, que não suporta arquivos ausentes, mas senti a necessidade de tentar uma solução mais "funcional" que funcione em tuplas:
#!/bin/bash
splitfile_renamer() {
mv splitfile$1 splitfile$2.csv
}
paste <(echo -en {a..z}"\n") <(seq 26) | while read args
do splitfile_renamer $args
done
O texto acima usa paste
para criar as tuplas de argumentos (separadas por espaço em branco) e as passa para uma função pré-criada que as utiliza como argumentos numerados.