Nomeei incorretamente arquivos que não estão sincronizados por -1. O problema é que preciso renomear milhares deles.
- DBGC180_805754
- DBGC180_805755
- DBGC180_805756
para
- DBGC180_805753
- DBGC180_805754
- DBGC180_805755
Eu preferiria usar scripts bash ou um comando unix.
Responder1
Você consegue fazer isso:
# {smallestfilenum..largestfilenum}
for i in {805754..999999}; do
mv "DBGC180_$i" "DBGC180_$(($i-1))";
done
Experimente com um número pequeno (digamos 805754..805758) para ter certeza de que funciona conforme o esperado. Esteja ciente de que se já existir um arquivo com o novo nome, ele será sobrescrito.
Responder2
- Mova os arquivos a serem renomeados para um subdiretório (sem alterar seus nomes).
- Renomeie os arquivos do subdiretório para o diretório original.
Há dois motivos pelos quais recomendo a etapa 1, mesmo que seja possível passar sem ela:
- Se o comando for interrompido, você poderá continuar de onde parou, pois fica imediatamente óbvio quais arquivos já foram renomeados e quais não foram.
- Você não precisa se preocupar em renomear na ordem errada e substituir um dos arquivos existentes.
Snippet de shell não testado (baseando-se no fato de que o número a ser decrementado nunca possui zeros à esquerda):
mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
number="${x##*_}"
mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement
Comzsh, você pode tornar isso muito mais simples, graças ao seuglob de intervalo numérico, isso éconstruídas emmv
que evita atingir limites de comprimento de linha de comando e seufunção de renomeação em massa baseada em padrão. Em zsh:
autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement
Responder3
Então, você deseja renomear DBGC180_805754
para DBGC180_805753
, ...55
para ...54
e assim por diante. Esse é o problema que abordarei.
Primeiro, coloque esse script em algum lugar do seu PATH
arquivo waltinator
.
#!/bin/bash
#step through the parameters
while [[ -n "$1" ]] ; do
oldname="$1"
# shift the arguments left
shift;
# strip off the fixed part of the old name
oldnum=${oldname##DBGC180_}
# decrement the number (this is what was wanted, right?)
newnum=$(( $oldnum - 1 ))
# build the new, improved filename
newname="DBGC180_$newnum"
if [[ -f "$newname" ]] ; then
printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
exit 1
fi
mv --no-clobber "$oldname" "$newname"
done
exit 0
Para a próxima etapa, suponha que o script esteja in $HOME/bin/waltinator
e você tenha does chmod +x $HOME/bin/waltinator
.
find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
sort | \
xargs $HOME/bin/waltinator
Os find
arquivos encontrados (sem nenhuma ordem específica), cujos nomes correspondem ao padrão shell glob " BDGC180_
seguido por 6 dígitos ( [0-9]
). Como queremos uma lista classificada (seria uma falha renomear ...97
antes ...96
de renomear ...96
), executamos a saída de find
through sort
. Em seguida, usamos xargs
a lista (classificada) de nomes de arquivos e construímos um comando para passar a lista (classificada) de nomes de arquivos $HOME/bin/waltinator
para Read man xargs
se você precisar encurtar a lista de argumentos.
A propósito, leia:
for page in bash mv find sort xargs ; do
man "$page"
done
Responder4
Use rename
para substituir cada número por ele mesmo menos 1.
$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'
Notas
rename
usa expressões Perl para renomear nomes de arquivos.s
especifica querename
substituirá alguns ou todos os nomes de arquivos que correspondem ao padrão de expressão regular.- As expressões de substituição Perl são estruturadas como tal.
s/PATTERN/REPLACEMENT/MODIFIER
\d{6}
é o padrão querename
irá procurar e substituir. São 6 dígitos decimais.$
é a variável que armazena a substring correspondente\d{6}
(neste caso, a "substring" é um int).sprintf("%06",($&-1))
recupera o valor armazenado em$
, decrementa-o e retorna esse valor como substituto. O%06
existe para lidar com zeros à esquerda.e
especificado querename
avalia a substituição como se fosse uma instrução Perl e usa seu valor de retorno como o texto de substituição.-v
fazrename
ecoar o que está fazendo.
Se você quiser ser mais seguro, use o sinalizador -n
para rename
informar apenas o que faria em vez de fazê-lo.
Isso parece funcionar apenas para diminuir, portanto, lide com isso com cuidado.