I have some files like this:



Now I want to change index numbers from i001 to i030 to A101 to A130 and i031 to i060 as A201 to A230..

I'm using "renamex" under FreeBSD primarily ( which has regex support )..

Usage: renamex [OPTIONS] filename ...
  -f, --file              Load file names from the file
  -l, --lowercase         Lowercase the file name
  -u, --uppercase         Uppercase the file name
  -s/PATTERN/STRING[/SW]  Replace the matching PATTERN with STRING.
                          The SW could be:
                          [i] ignore case when searching
                          [b] backward searching and replacing
                          [s] change file's suffix name
                          [r] PATTERN is regular expression
                          [e] PATTERN is extended regular expression
                          [g] replace all occurrences in the filename
                          [1-9] replace specified occurrences in the filename
  -R, --recursive         Operate on files and directories recursively
  -o, --owner OWNER       Change file's ownership (superuser only)
  -v, --verbose           Display verbose information
  -t, --test              Test only mode. Do not change any thing
  -h, --help              Display this help and exit
  -V, --version           Output version information and exit
  -A, --always            Always overwrite the existing files
  -N, --never             Never overwrite the existing files
Please see manpage regex(7) for the details of extended regular expression.

What do you suggest?

Edit: The ranges could be different. So it will not be 30 items always. For example A1 is 30 items, A2 is 40 items, A3 is 25 and so on...

  • Are there any gaps in the number ranges? Just wondering if you could do this with a simple script and mv. – Tigger Sep 27 '17 at 11:12
  • There may be some files missing in the range. – Plato Sep 27 '17 at 11:32

With zsh:

autoload zmv # best in ~/.zshrc
zmv -n '(file.)i(<->)(.trusted.txt)' '$1A$(($2+30+70*(($2-1)/30+1)))$3'

(remove the -n or pipe to sh when happy).

That would run:

mv -- file.i001.trusted.txt file.A101.trusted.txt
mv -- file.i002.trusted.txt file.A102.trusted.txt
mv -- file.i029.trusted.txt file.A129.trusted.txt
mv -- file.i030.trusted.txt file.A130.trusted.txt
mv -- file.i031.trusted.txt file.A201.trusted.txt
mv -- file.i032.trusted.txt file.A202.trusted.txt
mv -- file.i059.trusted.txt file.A229.trusted.txt
mv -- file.i060.trusted.txt file.A230.trusted.txt
mv -- file.i061.trusted.txt file.A301.trusted.txt
mv -- file.i062.trusted.txt file.A302.trusted.txt
mv -- file.i211.trusted.txt file.A801.trusted.txt
mv -- file.i212.trusted.txt file.A802.trusted.txt

You can replace <-> with <1-60> if you only want to process the first 60 ones.

If it's not always batches of 30, you can always run several zmvs:

i=1 j=100
for batch (30 40 30 50) {
  zmv -n "(file.)i(<$i-$((i+batch-1))>)(.trusted.txt)" \
  ((i += batch, j += 100 - batch))

Which gives:

mv -- file.i001.trusted.txt file.A101.trusted.txt
mv -- file.i030.trusted.txt file.A130.trusted.txt
mv -- file.i031.trusted.txt file.A201.trusted.txt
mv -- file.i070.trusted.txt file.A240.trusted.txt
mv -- file.i071.trusted.txt file.A301.trusted.txt
mv -- file.i100.trusted.txt file.A330.trusted.txt
mv -- file.i101.trusted.txt file.A401.trusted.txt
mv -- file.i150.trusted.txt file.A450.trusted.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.