Skip to content

mixmastamyk/prn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mike-rosoft™ Power File Renamer (c) 2003-2020

A tool to rename large numbers of files, such as MP3s or images. Recently ported to Python 3.6+ from ancient untouched 2.0-era source complete with its original silly name.

Background

In short, this tool operates on filenames in the order that they occur on the command-line. Why? So that results are consistent with expectations. Therefore, if the given modifications interact in unfortunate ways, they may be reordered to suit. This was a design goal.

The final rename happens at once however. No need to worry about renames occurring half-way.

Consequently, when performing many operations on an absolutley huge number of files, it might be less than instantaneous, due to the inefficiencies of looping through the argument list for each file. In such case you can run fewer operations per run, or change a subset of files at a time. As many filesystems are unhappy with huge numbers of files in a single folder, this limitation hasn't been found to be a problem in practice so far.

Note that the term PRN (from pro re nata in Latin), is used in the medical industry as an abbreviation for as needed. Therefore use prn as needed and directed under the supervision of a physician:

All information, content, and material of this website is for informational purposes only and are not intended to serve as a substitute for the consultation, diagnosis, and/or medical treatment of a qualified physician or healthcare provider.

"Do not taunt P.R.N.—Accept no substitutes!"

Installen-Sie, Bitte

⏵ pip3 install [--user] prn

Examples

A quick start with something simple—to replace underscores with spaces on some mp3s, try this, is shown below:

⏵ prn --replace _ ' ' *.mp3

Don't worry—this will simply show a preview of the results and won't do anything until confirmed, as we'll see later. Feel free to experiment, help is available of course:

⏵ prn -h  # or --help

Note: --longform options in the following examples have one-letter abbreviated aliases that are typically the first letter of the long form, e.g.:  --replace becomes -r.

Also, all options of prn can be passed multiple times, allowing more to be done in a single invocation and enabling relatively complex scenarios.

File Selection

There are several ways to select files for renaming.

  • As seen above, one may select several files from a folder holding additional files, by simply placing them on the command-line, with or without shell wildcard expansion:

    ⏵ prn foo.txt *.mp3
  • In a folder with huge numbers of files, command-line limits may be bypassed with --match 'GLOB' as shown below:

    ⏵ prn --match '*.mp3'  # OP1 OP2…
  • As one may want to exclude some of the files gathered, filter is available:

    ⏵ prn --filter 'Rick Astley*'  # Never gonna…
    

    Match and filter may be passed multiple times to sculpt the selected file set.

"You may dispense with the pleasantries Commander…"

  • Additionally, if there are no extraneous files in the current folder, selection criteria may be omitted. All files in the current folder will be selected instead:

    ⏵ prn --replace _ ' '

Recursive Mode

This will find files in and below the current folder.

When in recursive mode, note that folders aren't renamed. Too many issues came up, so to rename folders you'll have to rename them from each parent folder.

# all jpegs at or below this folder:
⏵ prn -R --match '*.jpeg' --replace .jpeg .jpg

Note that the glob method oddly requires a '**/' before the folder you want to walk. Power renamer handles that for you when a relative path is passed to match. When an absolute path is passed, you must handle it yourself.

Common String Operations

Numerous helpful string operations are also available:

  • -c --capitalize"Smart cap" each word
  • -l --lower --lower-ext
  • -u --upper
  • -s --strip
  • --insert STR --append STR --prepend STR

Simple Replace

We've already seen how --replace old new or its short form -r old new works above. It'll likely be the most used, workhorse operation.

Regular Expression Substitutions

When what you want to replace varies a bit between filenames, use a regex instead:

# collapse consecutive whitespace to a single space
⏵ prn --re-sub '\s+' ' '

-x … works as well. I find regex101.com very helpful when writing them.

Now you've got two problems, wink. 😉

Adding an Index Number

Several of the operations, such as replacement, insert, append, and prepend support an index number, assigned in the order of the file selection list. This helps when destination filenames will not be unique. Below we do a regex replace, substituting a GUID (of hex digits) with a zero padded index number:

⏵ prn --prepend img_ -x '[A-F\d-]+' '%02i' -r .jpeg .jpg

DEADBEEF-CAFE-123456.jpeg           │ img_00.jpg
DEADBEEF-CAFE-654321.jpeg           │ img_01.jpg

Without the formatted index number, these filenames would collide. A prefix is also added as well as a minor extension tweak.

Padding Frame Numbers

This option is relatively inflexible but did the one thing I needed:

⏵ prn --zfill 4 *.tif

foo.3.tif                           │ foo.0003.tif
foo.4.tif                           │ foo.0004.tif

Perhaps a more general pad function might be useful.

Swapping Text Trick

The zfill operation above, for example, may be problematic if there are digits before the desired group:

⏵ prn -z 4 *.tif

foo1.3.tif                          │ foo0001.3.tif  # Oops
foo1.4.tif                          │ foo0001.4.tif

Doh, one way to get around this (that can help in several other situations) is to hide the problem section while operating on other parts of the name. Below for example, we substitute base with "@", pad with zeros, then return original basename:

⏵ prn  -r foo1 @  -z 4  -r @ foo1  *.tif

foo1.3.tif                          │ foo1.0003.tif
foo1.4.tif                          │ foo1.0004.tif

This works since operation arguments are processed in order from left to right. Use a character for substitution that is not being used in the filenames, of course. Here we used the at symbol, but it could be any unique string.

See -h for further details.

Refine It!

At this point, you'll likely update the command-line a few times, until things are just to your liking, in terms of file selection and output filenames.

Newbie? Hitting the up arrow in the shell often brings your last command-line back for editing. Press Enter to see the results.

Can't See Enough?

prn shows each source and destination filename one per line, taking as much width as it can find on your terminal. Maximize the window if possible and/or shrink the font size to see more at once.

If the ends of filenames are still cut off, --align-right will it scroll them to the left.

Now, Commit Changes

Happy with the results? Finalize them with -e or --execute like so:

⏵ prn … … …  -e

Whoomp! There it is.

Safety

prn is written with safety in mind.

It won't make changes until you are happy with the results and pass the execute flag. It won't even try to rename files to destinations that already exist (or clobber them either), and will notify you beforehand when they do.

Despite its version number it has been used for (pushing two) decades now. However, as mentioned it was ported recently to Python3. There is a test suite but it is not currently extensive. Therefore:

☛  Make a backup before trusting prn with large or important file collections. ☚


About

A powerful script to rename files.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published