Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a series of files that are named according to field.%d.vtk and are generated when I run a C++ code. The codes does a series of computation inside a for-loop and dumps the output whenever i%N == 0 where i is the loop variable and N is a constant. By mistake I have set N = 1 and now I have huge amount of data that I do not need. I also do not want to rerun the code.

How can I write a bash script to only keep every N files, delete the rest, and rename the remaining files such that numbers in field.%d.vtk are contiguous? Sorry if this is trivial, but I have very limited experience with bash scripting.

EDIT: When N=1 (by mistake) range of %d would be in [0, 1, ..., O(100,000)] (really large) a suitable N is something around N=100 which would shrink down the number of files to O(1000) or so.


share|improve this question
Can you edit and add the range of %d right now and an example of a value for N that would be suitable? – Paul May 28 '12 at 4:05
up vote 3 down vote accepted

If N=100 then it is pretty easy to strip them down. The following will delete any files that don't end in 00.vtk

find -name '*.vtk' -not -name '*00.vtk' -exec rm {} +

So this would leave 100.vtk, 200.vtk etc

Then to make them contiguous, you can just strip out the 00:

rename 00.vtk .vtk *.vtk

This assumes standard posix rename. If you have the perl rename installed it is:

rename 's/00.vtk/.vtk/' *.vtk
share|improve this answer
for i in *.vtk
    [[ $i =~ \.([0-9]*)\. ]] && ((BASH_REMATCH[1] % 100 != 0)) && echo $i

Change echo to rm when you've double checked this command!

share|improve this answer

Bash( 4+)-only version of Paul's answer (so, it will only leave every 100th file .vtk file, those ending with 00.vtk, and will rename them by stripping the 00):

shopt -s extglob
rm ./!(*00).vtk
for f in ./*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done

If you want recursiveness:

shopt -s extglob globstar
rm ./**/!(*00).vtk
for f in ./**/*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .