Tengo una serie de archivos que se nombran según field.%d.vtk
y se generan cuando ejecuto un código C++. Los códigos realizan una serie de cálculos dentro de un bucle for y vuelcan la salida siempre i%N == 0
que i
la variable del bucle N
sea una constante. Por error lo configuré N = 1
y ahora tengo una gran cantidad de datos que no necesito. Tampoco quiero volver a ejecutar el código.
¿Cómo puedo escribir un script bash para conservar solo todos N
los archivos, eliminar el resto y cambiar el nombre de los archivos restantes de modo que los números field.%d.vtk
sean contiguos? Lo siento si esto es trivial, pero tengo una experiencia muy limitada con scripts bash.
EDITAR: Cuando N=1
(por error) el rango de %d
estaría en [0, 1, ..., O(100,000)] (realmente grande), lo adecuado N
es algo N=100
que reduciría el número de archivos a O(1000) más o menos.
Gracias
Respuesta1
Si N=100 entonces es bastante fácil eliminarlos. Lo siguiente eliminará cualquier archivo que no termine en 00.vtk
find -name '*.vtk' -not -name '*00.vtk' -exec rm {} +
Entonces esto dejaría 100.vtk, 200.vtk, etc.
Luego, para hacerlos contiguos, simplemente puedes eliminar el 00:
rename 00.vtk .vtk *.vtk
Esto supone un cambio de nombre posix estándar. Si tiene instalado el cambio de nombre de Perl, es:
rename 's/00.vtk/.vtk/' *.vtk
Respuesta2
for i in *.vtk
do
[[ $i =~ \.([0-9]*)\. ]] && ((BASH_REMATCH[1] % 100 != 0)) && echo $i
done
¡Cambie echo
a rm
cuando haya verificado dos veces este comando!
Respuesta3
Versión exclusiva de Bash (4+) de la respuesta de Paul (por lo tanto, solo dejará cada archivo .vtk número 100, los que terminan en 00.vtk
y les cambiará el nombre eliminando el 00
):
shopt -s extglob
rm ./!(*00).vtk
for f in ./*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done
Si quieres recursividad:
shopt -s extglob globstar
rm ./**/!(*00).vtk
for f in ./**/*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done