3

I have a large number of files with names file00.txt, file01.txt etc in a folder. Is it possible to rename all where the numbers will change to (4000+200*number) in terminal? I want the name of the final files as file4000.txt, file4200.txt etc. Thanks!!

2

3 Answers 3

7

If you have zsh installed...

autoload zmv
zmv -n '(file)(<->)(.txt)' '$1$((4000+$2*200))$3'

remove the -n if you're happy with the result.

6

I would normally use rename which makes use of perlre

$ rename -v 's/^(file)(\d+)(\.txt)$/$1 . (4000+200*$2) . $3/e' *.txt
file00.txt renamed as file4000.txt
file01.txt renamed as file4200.txt

or as Glenn Jackman suggests in the comments;

$ rename -v 's/(\d+)/4000 + 200*$1/e' file*.txt

Explanation:

This uses the s/foo/bar/ syntax which substitutes foo with bar.

foo is ^(file)(\d+)(.txt). So the expression will match any file starting with foo, containing 1 or more digits, followed by a .txt extension and nothing else. file is saved in capture group 1, the digits in capture group 2, and .txt in capture group 3.

Then we replace bar with our new filename: $1 . (4200 + $2) . $3. We are adding 4200 to capture group 2 (the digits) and concatenating that with $1 and $3.

We need the e modifier in s/foo/bar/e to ensure (4000 + 200*$2) and the concatenation is actually evaluated.

I added -v so it prints what is changed, but while testing, you'll want to use -n so it doesn't change anything until you are happy with what it will actually do.

The last argument to the rename command is *.txt. This is simply the list of files to evaluate. Since we do a check for the extension in perlre, we could just use a * here. Anything that doesn't match (foo) will not be changed.

This answer uses file-rename from Debian's package rename which uses update-alternatives to provide /usr/bin/rename. If you don't have that package installed, you may have rename.ul from util-linux. rename.ul uses different expression system and will not work with what I've described here.

2
  • 1
    Can be slightly simplified: rename -v 's/(\d+)/4000 + 200*$1/e' file*.txt (fixed the formula in passing) Mar 22 at 13:46
  • 3
    Note that this assumes perl-rename, while on many systems, the rename command is actually rename from util-linux instead. Oh, and the OP wants 4000 + (200 * $2), so not adding 4200, but adding 4000 to the result of multiplying the number by 200.
    – terdon
    Mar 22 at 13:49
1

If you don't want to rename all of the files and you just want to rename some of the files within a certain range, then a modified version of the solution from this answer to How to rename files with sequential names to an another sequence using Terminal? may be of some use.

For example, to rename just file05.txt through to file11.txt to file5000.txt to file7200.txt:

for index in {05..11}; do echo mv file"${index}".txt file"$((4000+index*200))".txt; done

The echo is there just to test that the command does what you expect it to. Remove the echo once the output looks correct.

Note for single digits (numbers <10)

For the files in the file01.txt to file09.txt range, a 0 must be added to precede the single digit in the range. Therefore, instead of

for index in {5..11};

you would put

for index in {05..11};

For a range of double digits, then the preceding 0 is not required. For example, for 13 to 25:

for index in {13..25};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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