Remover data e hora recursivamente de nomes de arquivos

1

Eu tenho uma pasta que contém pastas que contém arquivos do formulário

resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr

Eu quero remover a data e a hora de cada um deles, portanto, neste caso, obtenha

resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr

Como faço isso no bash?

    
por Make42 27.05.2017 / 17:32

5 respostas

1

Se você realmente quiser fazer "com bash" ,

find . -name '*.wcr' -execdir bash -c '
  shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +

Isso depende do glob% estendido+([0-9-]) que corresponde a uma ou mais ocorrências de caracteres no conjunto [0-9-]

Você poderia tornar a substituição mais específica, por exemplo ${f/_2017+([0-9-])_/_} se simplesmente combinar dígitos e traços é muito genérico.

Observação: remova o echo quando tiver certeza de que está fazendo o que deseja.

    
por 27.05.2017 / 18:03
1

Use os comandos find + prename (renomear Perl):

find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +

Para visualizar prename result sem ação, adicione -n option ( imprima os nomes dos arquivos a serem renomeados, mas não renomeie ):

man rename
  • [0-9]{4}-[0-9]{2}-[0-9]{2} - padrão apontando para uma substring parecida com data (por exemplo, 2017-05-26 )
por 27.05.2017 / 17:48
1

Usando o comando renomear perl (variante, mas não o util-linux rename ):

find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +
    
por 27.05.2017 / 19:21
1
for i in ./*/*; do
  j='echo "$i" | cut -d'_' -f1-2,4-'
  mv "$i" "$j"
done

Essa não é a solução mais elegante, mas funciona bem, presumindo que você queira renomear todos os arquivos em subdiretórios e todos eles correspondem a esse padrão.

    
por 27.05.2017 / 17:51
0

Se os arquivos sempre tiverem um nível de diretório profundo, você poderá iterar sobre eles com algo como for x in */*_20*_* . Qual padrão usar depende de quais outros arquivos podem estar presentes que você não deseja renomear. O padrão que acabei de dar pressupõe que a data começa com 20 e que todos os arquivos cujo nome contenha _20 e outra descontinuação depois disso devem ser renomeados.

Você pode renomear com um loop de shell, usando expansão de parâmetro constrói para construir o novo nome de arquivo.

for old_name in ./*/*_20_*_*; do
  base=${old_name##*/}        # remove the directory part
  prefix=${base%%_20*}        # remove everything from _20
  suffix=${base#*_20}         # remove everything up to _20
  suffix=${suffix#*_}         # ... then everything before the first remaining _
  mv "$old_name" "${old_name%/*}/${prefix}_${suffix}"
done

Se os arquivos estiverem em profundidades variadas, no bash ≥4.3, você poderá executar shopt -s globstar , em seguida, for x in **/*_20*_*; … . O padrão ** corresponde a qualquer profundidade de diretório se globstar estiver ativado . Isso também funciona no bash 4.0–4.2 com a ressalva de que ele também percorre links simbólicos para diretórios. Isso também funciona em zsh e ksh, sem a ressalva, fora da caixa em zsh e com set -o globstar em ksh.

    
por 28.05.2017 / 02:29