como aumentar a extensão do arquivo numericamente por um

2

na seguinte pasta atual, temos o exemplo de arquivos

lok.log.1
df.log.6
weq.log.90
vr.log.11
vs.aw.frsd.log.3

queremos aumentar a extensão dos arquivos em 1

para que a saída esperada seja a seguinte

lok.log.2
df.log.7
weq.log.91
vr.log.12
vs.aw.frsd.log.4

por favor, conselhos sobre como renomear os arquivos com find e regex

  • O conceito deve ser todos os arquivos que possuem ".log" serão renomeados por +1
por yael 03.10.2018 / 17:27

2 respostas

5

com zsh :

autoload zmv # best in ~/.zshrc
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'

(remova o -n se satisfeito com o resultado)

  • <-> corresponde a qualquer número decimal
  • (#qnOn) : qualificador glob aqui para classificar numericamente a lista de arquivos ( n ) na ordem inversa pelo nome ( On ), então file.log.2 é renomeado para file.log.3 antes de file.log.1 ser renomeado para file.log.2 . Adicione . se você quiser renomear apenas arquivos regulares (mas provavelmente você desejaria adicionar uma opção -o-nT assumindo o GNU mv ) e D se você também quiser renomear oculto arquivos.
  • -f desativa a salvaguarda que cancelaria esse comando quando um arquivo fosse renomeado para um arquivo existente que atrapalharia nosso file.log.1 , file.log.2 exemplo acima. Ele ainda protegeria contra o foo.log.1 e o foo.log.01 sendo renomeados para foo.log.2 .

Recursivamente:

zmv -n -f '(**/)(*.log.)(<->)(#qnOn)' '$1$2$(($3+1))'

De bash ou sh ou ksh :

zsh << 'EOF'
autoload zmv
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'
EOF

Com bash e sem usar zsh , e se você tiver o GNU ls e o GNU mv e a lista de arquivos não for muito grande, você pode fazer algo com:

shopt -s failglob
shopt -s extglob
export LC_ALL=C
eval "files=($(
  ls --quoting-style=shell-always -rvd -- *.log.+([[:digit:]])))"
for f in "${files[@]}"; do
   echo mv -nT -- "$f" "${f%.*}.$((10#${f##*.} + 1))"
done

(remova echo quando satisfeito).

Recursivamente, com GNU bash , GNU find , GNU mv e GNU sort , apenas para arquivos regulares:

export LC_ALL=C
while IFS= read -rd '' -u3 file; do
  echo mv -nT "$file" "${file%.*}.$((10#${file##*.} + 1))"
done 3< <(
  find . -name '.?*' -prune -o -regex '.*\.log\.[0-9]+' -type f -print0 |
    sort -rzV)

mv -n é uma extensão do GNU para evitar a destruição de arquivos existentes e -T para remover a ambigüidade entre mover para e mover para quais mv sofrem de. No entanto, observe que quando um arquivo não é renomeado por causa de -n , você não recebe nenhum erro sobre isso.

    
por 03.10.2018 / 17:38
0

rename é perl -based e permite o uso de aritmética (algumas distros usam o nome prename para essa ferramenta de renomeação perl ):

rename 's/(log.)([0-9]+)$/$1.($2+1)/e' <files>

Para combinar com a localização, use:

find <search options> -exec rename 's/(log.)([0-9]+)$/$1.($2+1)/e' {} +

Edite o seguinte comentário de Stéphane:

A saída não classificada de find pode, na verdade, incomodar você e é melhor que ela seja classificada de antemão. Podemos usar a ordenação reversa (!) E sua opção de numeração de versão para os padrões de nome fornecidos:

find <search parpameters> -print0 |\
   sort -rzV |\
   xargs -r0 rename 's/(log.)([0-9]+)$/$1.($2+1)/e'
    
por 03.10.2018 / 22:22