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 prename
o resultado sem ação, adicione -n
a 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 exemplo2017-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 20
e que todos os arquivos cujo nome contém _20
e 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 globstar
o for x in **/*_20*_*; …
. Opadrã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 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 globstar
em ksh.