0

EDIT: My original goal was to use Regular Expressions in Pro Tools' "Batch Rename" dialogue. Regular Expressions in Pro Tools doesn't support something as specific as this. The question has shifted to how to achieve the following by batch renaming files in Finder using an Automator app with the Run Shell Script command.

Original question:

I'd like to batch rename many items in a program that supports batch renaming using regular expressions (Pro Tools). What do I need to enter in the "Find" and "Replace" fields to replace all text proceeding _rr with sequential numbering (1, 2, 3, etc.) that restarts every time the string preceeding _rr changes?

I've gotten as far as Find: _rr(.*), but I can't figure out how to create a number sequence that restarts based on preceding text patterns/changes.

For a concrete example, take this set of data:

Casio AA_12_Test_A3_rr_01-03
Casio AA_12_Test_A3_rr_01-04
Casio AA_12_Test_A4_rr_01-03
Casio AA_12_Test_A4_rr_01-05
Casio AA_12_Test_A4_rr_01-06
Casio AA_12_Test_B5_lng_rr_01-04
Casio AA_12_Test_B5_lng_rr_01-05
Casio AA_12_Test_B5_sht_rr_01-02
Casio AA_12_Test_B5_sht_rr_01-05
Casio AA_12_Test_E4_sht_rr_01-02
Casio AA_12_Test_E4_sht_rr_01-07
Casio AA_12_Test_E5_sht_rr_01-04
Casio AA_12_Test_E5_sht_rr_01-05-01
Casio AA_12_Test_F5_lng_rr_01-05
Casio AA_12_Test_G4_lng_rr_01-04-01

What regular expression would yield the following?

Casio AA_12_Test_A3_rr1
Casio AA_12_Test_A3_rr2
Casio AA_12_Test_A4_rr1
Casio AA_12_Test_A4_rr2
Casio AA_12_Test_A4_rr3
Casio AA_12_Test_B5_lng_rr1
Casio AA_12_Test_B5_lng_rr2
Casio AA_12_Test_B5_sht_rr1
Casio AA_12_Test_B5_sht_rr2
Casio AA_12_Test_E4_sht_rr1
Casio AA_12_Test_E4_sht_rr2
Casio AA_12_Test_E5_sht_rr1
Casio AA_12_Test_E5_sht_rr2
Casio AA_12_Test_F5_lng_rr1
Casio AA_12_Test_G4_lng_rr1
gills
  • 95
  • 1
  • 10
  • regular expressions don't "yield" anything. All they do is match. To "do" something you need a tool/language that changes the output. What tool are you using? – Bohemian Mar 31 '21 at 00:29
  • I'm using the Batch Rename function in Pro Tools. "Find" and "Replace" is the tool I think. I thought it was possible to insert regular expressions in both the Find and Replace fields and they would relate to each other, much like the Substitution function on www.regex101.com – gills Mar 31 '21 at 00:49
  • you'd probably be better off asking on https://duc.avid.com but from a quick look at the [manual](https://resources.avid.com/SupportFiles/PT/Pro_Tools_Reference_Guide_2021.3.pdf) it may not be possible – jhnc Mar 31 '21 at 01:02
  • .Net regex rename allows one to provide a match evaluator lamda which on a match a state could be kept and the pattern you discuss could be generated and returned for each distinct replace. If you are looking to rename files, you might want to use a different tool such as powershell. – ΩmegaMan Mar 31 '21 at 01:41
  • @jhnc I'm confident duc.avid.com won't be able to help me. I've posed several questions there in the past with no response. What I'm trying to do is more of a programming thing anyway. – gills Mar 31 '21 at 19:15
  • @ΩmegaMan I don't really understand most of that, but if I simply did this renaming on a large batch of files (which I'd export from Pro Tools with the un-processed / incorrect filenames), would it be possible to make an application using macOS Automator that receives files as the input and uses the Run Shell Script action to rename all of those files according to my goal? – gills Mar 31 '21 at 19:18

1 Answers1

0

I don't think the "batch rename" functionality of Pro Tools will be able to do the counting you want.

You mention using automator with a shell script. Set "pass input" to "stdin" and create a script like:

#!/bin/sh

dir="/somewhere/to/keep/undo/logs"
now=$(date +%Y%m%d%H%M%S.$$)
logfile="$dir/undo.$now.command"

echo '#!/bin/sh' >"$logfile"
chmod +x "$logfile"

sort | awk -F_rr_ -v undo="$logfile" '
   function q(s,d){
      d="\47"
      gsub(d,"&\\\\&&",s)
      return d s d
   }
   !a[$1]++{ i=1 }
   $2{
      src=q($0)
      split($2,a,/^.*\./)
      if(a[2])ext="."a[2]
      dst=q($1"_rr"(i++)ext)
      print("mv",dst,src) >> undo
      print("mv "src" "dst)
   }
'

This is untested as I don't have a Mac.

  • create (hopefully unique) name for undo script
  • echo - initialise undo script
  • chmod - make the undo script executable
  • sort - ensure filename list (read from stdin) is in order
  • -F_rr_ - tell awk to split input records on _rr_
  • q(s) - single-quote s to ensure odd characters don't cause problems when passed to shell
  • !a[$1]++ - common idiom to only match first time particular $1 is seen. used here to reset counter i
  • $2{ - only do action if filename contained _rr_ (if it didn't, $2 will be empty
  • split - look for filename extension, store in array element a[2]
  • if(a[2])... - if file extension found, initialise ext
  • print(...) >> undo - append undo commands to undo script
  • print(...) - generate actual rename commands

To actually rename files, replace second print with system.


It seems that MacOS cares about the extension when double-clicking from finder. This answer indicates executable scripts with .command extension will run in a terminal window.

jhnc
  • 11,310
  • 1
  • 9
  • 26
  • This works perfectly, thank you so much! The only potential problem I see is that the batch rename can't be undone. Is it possible to create an undo step in Finder for the batch of renames, in case something goes wrong? – gills Apr 01 '21 at 21:06
  • someone else will have to answer - I've never used a mac – jhnc Apr 01 '21 at 21:13
  • Ok, thanks for your help! I'm going to hold off on marking this as the solution for a bit in the hopes that someone will be able to answer that final question of an undo step. Will mark this off as solution if no one is able to help after awhile. – gills Apr 01 '21 at 21:43
  • A quick google seems to indicate undo isn't possible but presumably nothing prevents you logging the generated commands into an undo shellscript. – jhnc Apr 01 '21 at 21:58
  • Ahh I tried your updated shellscript code, and eventually was able to find a location to save the undo files to that wouldn't yield an error message, but it no longer does the batch renaming for some reason. – gills Apr 01 '21 at 23:16
  • thanks so much for all the help! that does make it run with the proper batch renaming again, and it does create an undo file, but it doesn't actually let me undo, unless I'm missing something. I guess it's a pretty unideal workflow to working out code in this way :-) I really don't know anything about shell scripts and very little about coding, but maybe it really would be better for someone on a Mac to figure out how to achieve this – gills Apr 02 '21 at 00:13
  • A couple of other behaviors that would be useful: 1) This should ideally ignore any files that don't have "_rr" in the filename. Currently it will add "rr[#]" to any file that gets input. 2) If a folder is the input, then only the files within the folder (and subfolders) are acted upon, and folders themselves should always be ignored. – gills Apr 02 '21 at 01:26
  • shell scripts either need to be executable or used as `sh script.sh`. matching only `_rr_` is easy. there are many ways to implement file selection, depending on criteria (what if a folder given contains subfolders, for example?) – jhnc Apr 02 '21 at 13:00
  • If I understand what "executable" means, I'm pretty sure that's what I'm doing. I'm making an application (.app) using Automator, which runs an executable within its contents when I drag files onto it. It doesn't add an undo step to Finder though, only creates an undo.[#].sh file. Looks like the $2{ addition worked perfectly. For file selection, I was thinking all non-folder files up to maybe 3 subfolder levels, if a folder is dragged onto it. And if individual files to be renamed are dragged, that that would also work on the dragged files. – gills Apr 02 '21 at 18:11
  • Creating undo steps has proven to be more problematic than is worthwhile, so I ended up reverting to the old version. I'm realizing a new problem though: the renames strip the file type extension from the filename. This wouldn't be a big deal, except it causes the files to no longer be seen as audio files by macOS. (Manually deleting a filename extension doesn't do this, so I'm not sure why this happens). How would I add to the code so that ".wav" or whatever filename extension exists (if one exists) doesn't get deleted? – gills Apr 19 '21 at 21:43
  • extensions aren't shown in your question but assuming they are the part of the filename after any final period, they're easy enough to retain – jhnc Apr 20 '21 at 00:49