Renomear lote, adicionar caractere extra “.” na posição 3 no nome do arquivo, recursivamente

1

Eu tenho lutado para fazer isso funcionar, mas não sou muito bom com a regex. Foi isso que tentei fazer e não funcionou (depois de 50 minutos, continuando sem alterações visíveis):

while IFS= read -r -d '' file; do mv $file ${file:0:2}.${file:2}; done

Obrigado antecipadamente!

    
por BlackR 30.03.2015 / 00:00

3 respostas

1

Um problema que você terá que enfrentar ao renomear arquivos em diretórios de forma recursiva é separar o nome do arquivo (que você deseja modificar) do caminho. Você não pode simplesmente remover o componente do caminho, porque seus arquivos acabarão sendo movidos em vez de simplesmente renomeados.

Para usar seu método original, acho que você precisa fazer algo como

while read -r -d '' f; do 
  file="${f##*/}"; path="${f%/*}" 
  echo mv -- "$path/$file" "$path/${file:0:2}"."${file:2}"
done < <(find -type f -iname "*.wav" -print0)

Outra opção é usar o find do comando -execdir em vez de -exec . Eu penso que é seguro assumir que os resultados serão apresentados ao seu comando rename (se você usa rename ou mv ) com apenas um ./ como o caminho, nesse caso você pode fazer

find -type f -iname "*.wav" -execdir rename -nv -- 's|\./..|$&.|' {} +

ou usando uma variante mais perl-ish

find -type f -iname "*.wav" -execdir rename -nv -- 's|\./..\K|.|' {} +

ou usando algo mais equivalente à sua abordagem mv original

find -type f -iname "*.wav" -execdir bash -c 'echo mv -- "$0" "${0:0:4}"."${0:4}"' {} \;

(note que os índices de substring foram aumentados em 2 para permitir o componente% path ./ ).

Se a sua versão de find não tiver a opção -execdir , você poderá modificar a rename regex para pular o prefixo de caminho correspondente mais longo, por exemplo,

find -type f -iname "*.wav" -exec rename -nv -- 's|.*/..\K|.|' {} +

Nota: todas essas expressões têm opções "no-op" (renomear a opção -n ou um comando echo ) para que você possa verificar o que faria antes de confirmar .

    
por steeldriver 30.03.2015 / 03:21
0

Isso pode ser feito facilmente usando rename :

rename 's/ /\./' file.txt

Exemplo:

$ ls -l
-rw-rw-r-- 1 user user 0 Mar 30 04:22 01 Song Title.flac
$ rename 's/ /\./' 01\ Song\ Title.flac 
$ ls -l
-rw-rw-r-- 1 user user 0 Mar 30 04:22 01.Song Title.flac

EDITAR: Se você quiser um espaço depois de 01. :

rename 's/ /\. /' file.txt

Se você quiser todos os arquivos no diretório /directory/to/search e sob todos os seus subdiretórios com a extensão .wav renomeada como esperado, tente isto:

find /directory/to/search -type f -name "*.wav" -execdir rename 's/(^\d+) /$1. /' {} +

Para se tornar insensível a maiúsculas e minúsculas:

find /directory/to/search -type f -iname "*.wav" -execdir rename 's/(^\d+) /$1. /' {} +
    
por heemayl 30.03.2015 / 00:25
0

Isso funciona (testado):

#!/bin/bash

filenames=$(find . -type f) # stores all filenames in $filenames
for filename in $filenames; do # for each member in $filenames
    newfilename=$(echo "$filename" | sed 's/\(.*\)\/\(..\)\(.*\)$/\/\./') # edits $filename by adding a . after the second character and stores the edited string in $newfilename
    mv "$filename" "$newfilename" # renames $filename to $newfilename
done
    
por kos 30.03.2015 / 05:37