Remova data e hora recursivamente dos nomes de arquivos

Remova data e hora recursivamente dos nomes de arquivos

Eu tenho uma pasta que contém pastas que contém arquivos no formato

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

Quero remover a data e a hora de cada um deles, então, neste caso, obtenha

resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr

Como faço isso no bash?

Responder1

Se você realmente quer fazer isso"com festança", então

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

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

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

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

Responder2

Usar find+prename(Renomear Perl) comandos:

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

Para visualizar prenameo resultado sem ação, adicione -na opção (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 paradata-like substring (por exemplo 2017-05-26)

Responder3

Usando oPerl renomearcomando (qualquer 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+_/_/' {} +

Responder4

Se os arquivos tiverem sempre um nível de diretório, você poderá iterá-los com algo como for x in */*_20*_*. O padrão a ser usado depende de quais outros arquivos podem estar presentes e que você não deseja renomear. O padrão que acabei de fornecer assume que a data começa com 20e que todos os arquivos cujo nome contém _20e outro undescore depois disso devem ser renomeados.

Você pode renomear com um shell loop, usandoexpansão de parâmetrosconstró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 globstaro for x in **/*_20*_*; …. Opadrão**corresponde a qualquer profundidade de diretório se globstarestiver ativado. Isso também funciona no bash 4.0–4.2 com a ressalva de que também atravessa links simbólicos para diretórios. Isso também funciona em zsh e ksh, sem ressalva, pronto para uso em zsh e com set -o globstarem ksh.

informação relacionada