Eu tenho uma série de arquivos que são nomeados de acordo field.%d.vtk
e são gerados quando executo um código C++. Os códigos fazem uma série de cálculos dentro de um loop for e despejam a saída sempre que i%N == 0
onde i
é a variável do loop e N
é uma constante. Por engano eu configurei N = 1
e agora tenho uma enorme quantidade de dados que não preciso. Também não quero executar novamente o código.
Como posso escrever um script bash para manter apenas todos N
os arquivos, excluir o restante e renomear os arquivos restantes de forma que os números field.%d.vtk
sejam contíguos? Desculpe se isso é trivial, mas tenho experiência muito limitada com scripts bash.
EDITAR: Quando N=1
(por engano) o intervalo %d
estaria em [0, 1, ..., O(100.000)] (muito grande), um adequado N
é algo em torno N=100
do qual reduziria o número de arquivos para O(1000) ou mais.
Obrigado
Responder1
Se N = 100, então é muito fácil eliminá-los. O seguinte excluirá todos os arquivos que não terminam em 00.vtk
find -name '*.vtk' -not -name '*00.vtk' -exec rm {} +
Então isso deixaria 100.vtk, 200.vtk etc.
Então, para torná-los contíguos, você pode simplesmente retirar o 00:
rename 00.vtk .vtk *.vtk
Isso pressupõe a renomeação posix padrão. Se você tiver a renomeação perl instalada, é:
rename 's/00.vtk/.vtk/' *.vtk
Responder2
for i in *.vtk
do
[[ $i =~ \.([0-9]*)\. ]] && ((BASH_REMATCH[1] % 100 != 0)) && echo $i
done
Mude echo
para rm
quando você verificar este comando!
Responder3
Versão somente Bash (4+) da resposta de Paul (portanto, ele deixará apenas cada 100 arquivos .vtk, aqueles que terminam com 00.vtk
, e os renomeará removendo o 00
):
shopt -s extglob
rm ./!(*00).vtk
for f in ./*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done
Se você quiser recursividade:
shopt -s extglob globstar
rm ./**/!(*00).vtk
for f in ./**/*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done