classificando nomes de arquivos numericamente quando eles possuem um prefixo não numérico [duplicado]

5

Eu tenho arquivos no seguinte formato: x1 x2 ... x10 x11 ... x101 ...

Eu quero renomear esses arquivos para que todos tenham o mesmo tamanho de nome: x001 x002 ... x010 ...

Eu posso fazer isso com arquivos, que não têm o prefixo não numérico (usando apenas sort -n seguido por while read x; ), mas o tipo não reconhece o valor numérico, quando não está no começo do nome do arquivo.

    
por Let_Me_Be 19.07.2011 / 11:00

4 respostas

6

Você pode tentar classificar os arquivos usando a opção v (versão) de ls , por exemplo. %código%. Ou você pode usar a classificação numérica com ls -1v como o delimitador: x

Mas você não precisa classificar os arquivos para renomeá-los. Você pode apenas olhar o comprimento do nome do arquivo e preenchê-lo com zeros, se necessário. Aqui está um pequeno script que faz isso:

prefix=x
maxLength=4

for file in ${prefix}*
do
 if [ ${#file} -lt $maxLength ]
 then
     newFile=$file
     while [ ${#newFile} -lt $maxLength ]
     do
       newFile=${newFile/$prefix/${prefix}0}
     done   
     mv $file $newFile
 fi
done
    
por 19.07.2011 / 11:17
5

Tem certeza de que precisa classificá-los primeiro?

m=0
for f in x*; do
  [ "${#f}" -gt "$m" ] &&
    m=${#f}
done

for f in x*; do
  echo mv -- "$f" "${f%${f#?}}$( printf '%0.*d' $(( m - 1 )) "${f#?}" )"
done 

Se a sua implementação printf não suporta a sintaxe acima, use printf "%0.$(( m - 1 ))d" "${f#?}" .

Remova o eco quando estiver satisfeito.

    
por 19.07.2011 / 11:22
3

Apenas para elaborar a resposta do dogbane, sort tem uma opção de classificação de versão. Observe que algumas plataformas (por exemplo, busybox) não têm essa opção.

Você pode usá-lo assim:

sort -V
sort --version-sort

Ou para a versão, classifique a n'ésima coluna:

sort -knV
    
por 16.09.2015 / 04:25
2

Você precisa renomear, embora haja ferramentas semelhantes, que também podem ser úteis para você:

touch x1 x2 x10 x11 x101 
ls ; rename 's/x/x0/' x[0-9] 

x1 x10 x101 x11 x2

ls ; rename 's/x/x0/' x[0-9][0-9] 

x01 x02 x10 x101 x11

ls

x001 x002 x010 x011 x101

'renomear' faz parte de algum pacote perl, se você precisar instalá-lo, pelo menos disponível para Linux.

Sem renomear, há uma solução semelhante com um loop:

rm * 
touch x1 x2 x10 x11 x101
for f in  x[0-9] ; do mv $f ${f/x/x0}; done 
for f in  x[0-9][0-9] ; do mv $f ${f/x/x0}; done ; ls 

x001 x002 x010 x011 x101

    
por 19.07.2011 / 15:30