Tengo una carpeta que contiene carpetas que contienen archivos del formulario
resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr
Quiero eliminar la fecha y la hora de cada uno de estos, así que en este caso obtenga
resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr
¿Cómo hago esto en bash?
Respuesta1
Si realmente quieres hacerlo"con bash", entonces
find . -name '*.wcr' -execdir bash -c '
shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +
Esto se basa en un globo extendido +([0-9-])
que coincide con una o más apariciones de caracteres en el conjunto.[0-9-]
Podría hacer que el reemplazo sea más específico, por ejemplo, ${f/_2017+([0-9-])_/_}
si simplemente hacer coincidir dígitos y guiones es demasiado genérico.
Nota: retire el echo
una vez que esté seguro de que está haciendo lo que desea.
Respuesta2
Usar find
+prename
(cambiar el nombre de Perl) comandos:
find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +
Para ver prename
el resultado sin acción, agregue -n
la opción (imprimir los nombres de los archivos a los que se les va a cambiar el nombre, pero no cambiar el nombre):
man rename
[0-9]{4}-[0-9]{2}-[0-9]{2}
- patrón apuntando afecha-como subcadena (por ejemplo2017-05-26
, )
Respuesta3
Utilizando elcambiar el nombre de perlcomando (cualquier variante, pero no util-linux rename
):
find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +
Respuesta4
Si los archivos siempre tienen un nivel de directorio de profundidad, entonces puedes iterar sobre ellos con algo como for x in */*_20*_*
. El patrón a utilizar depende de qué otros archivos puedan estar presentes cuyo nombre no desee cambiar. El patrón que acabo de dar supone que la fecha comienza con 20
y que se debe cambiar el nombre de todos los archivos cuyo nombre contenga _20
y otro undescore posterior.
Puedes cambiar el nombre con un bucle de shell, usandoexpansión de parámetrosconstruye para construir el nuevo nombre de archivo.
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
Si los archivos tienen diferentes profundidades, en bash ≥4.3, puede ejecutar shopt -s globstar
entonces for x in **/*_20*_*; …
. Elpatrón**
coincide con cualquier profundidad de directorio si globstar
está activado. Esto también funciona en bash 4.0–4.2 con la salvedad de que también atraviesa enlaces simbólicos a directorios. Esto también funciona en zsh y ksh, sin la advertencia, listo para usar en zsh y con set -o globstar
ksh.