3

I have a directory which contains a number of subdirectories with names on the format dir.##. The prefix is always the same, and the suffix is 1-3 digits in a strictly incrementing sequence. Thus, something similar to:

dir.0
dir.1
dir.2
dir.3
...
dir.9
dir.10
dir.11
...
dir.298
dir.299
dir.300

First, I want to delete the first few such directories. This is trivial.

Then, I want to rename all subsequent directories to shift the numerical suffixes such that e.g. dir.7 becomes dir.0, dir.8 becomes dir.1, dir.10 becomes dir.3, etc. That is, shift each suffix (treated as a number) by a given, constant offset.

How do I perform such a rename operation without renaming each directory separately and manually?

I'm okay with using a separate tool for it, but it would be nice if I can do it all in bash without "exotic" software.

user
  • 28,901

3 Answers3

7

This decrementing can be done in a pretty low-tech way: generate the list, start at the beginning. It's not that easy to “productize” by handling all cases, but it's little more than a one-liner if you're willing to hard-code things like the maximum number of digits and to assume that there are no other files called dir.*. Using bash syntax, tuned towards less typing:

i=0
for x in dir.{?,??,???}; do
  mv "$x" "${x%.*}.$i"
  ((++i))
done

Note that it has to be dir.{?,??,???} and not dir.* to get dir.9 before dir.10.

In zsh you could make this a little more robust at no cost, by using <-> to expand to any sequence of digits and (n) to sort numerically (dir.9 before dir.10).

i=0
for x in dir.<->(n); do
  mv $x ${x%.*}.$i
  ((++i))
done
  • 1
    The bash example (with Glenn's edit for the substitution expression) did exactly what I wanted. Thank you both! – user Dec 03 '12 at 22:08
1

Another approach:

n=7   # number to delete
max=$(printf "%s\n" dir.* | grep -o '[[:digit:]]*' | sort -n | tail -1)
for (( i=0; i<n; i++)); do rm -r "dir.$i"; done
for (( i=n; i<=max; i++ )); do mv "dir.$i" "dir.$((i-n))"; done
glenn jackman
  • 85,964
  • The quotes in the rm and mv command arguments are not strictly necessary since we know the contents of the generated directory name will not contain whitespace. – glenn jackman Dec 04 '12 at 00:02
  • 1
    while technically true, quoting is generally considered best practice. – laebshade Dec 04 '12 at 03:44
0

You can also use graphical tool KRename.

Here are the steps:

  1. choose files
  2. choose option to rename files
  3. turn on JavaScript plugin\
  4. set field Prefix to empty, Suffix: empty, Filename: use original name, Extension: other extension: [js;krename_extension-OFFSET] where OFFSET is value that you need to decrement.
pbm
  • 25,387