Author Topic: Rename file script  (Read 878 times)

SpiroC

  • Newbie
  • *
  • Posts: 2
    • View Profile
Rename file script
« on: November 08, 2017, 01:10:51 »
Hi.  I couldn't find a way to launch MultiRename profiles on a button or menu, so I wrote a rename script which I am sharing here.  You can duplicate it, tweak it, then put it on a dedicated menu or button.
Pros:
- Can be put on a menu/button
- Can do some things that MultiRename dialog can't (obviously, because it's a programming environment), but it's harder to use.  Once you set it up on buttons though it's all good.
- Works for multiple files selected
- Works in branch view (different paths)

Cons:
- No regex grouping/capture.  So you can't replace (.*) with $1.  This is a big weakness. 
- I couldn't find any StrRegexReplace or any way of knowing how long the match is after StrIsRegExpMatch() returns with a successful find.  I used a messy guess and check iteration to find a match, but it's non-greedy and inflexible.  I'd really like a StrRegexReplace() library function.
- Inefficiency: scRegexExtract(), scRegexDelAfterMatch() and scRegexReplace() only vary slightly.  They should be consolidated into 1 routine.
- No undo.

Notes:
- A popup showing changes is presented giving you the chance to op-out before and filename changes are made.
- Top function MakeNewName() is called once per file.  There are examples in this function (including regex replace, proper case, base reversal, pre/app date).  Uncomment them to try them out.

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function MakeNewName($fbase, $fext)
{
   @var $now = GetTime();
   @var $date = FormatDate( "yyyy-MM-dd" , $now );
   @var $seasonepisode;

   // Regex replace base only
   //$fbase= scRegexReplace($fbase, "t.", "AAA", 0);

   // Regex replace global, base only
   //$fbase= scRegexReplaceGlobal($fbase, "(t|T).", "ZZZ", 0);

   // Regex replace, global, case insensitive, base only
   //$fbase= scRegexReplaceGlobal($fbase, ".", "_", 1);

   // Reverse string, base only
   //$fbase = scReverse($fbase);

   // Append date to base
   //$fbase = $fbase + " " + $date;

   // Prepend date to base
   $fbase = $date + " " + $fbase;

   // Regex delete after match case insensitive (base only)
   //$fbase = scRegexDelAfterMatch($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   // Proper case base only (Only capitalises.  You need to lowercase first manually.  See examples below)
   //$fbase = scProperCase($fbase);

   // TV Show filename cleanup 1 (Aggresive. Removes episode name and cleans up various things)
   //$fbase= scRegexReplaceGlobal($fbase, "_", " ", 0);
   //$fbase = StrTrim($fbase, " ");
   //$seasonepisode = scRegexExtract($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = scRegexDelAfterMatch($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = StrToLower($fbase);
   //$fbase = scProperCase($fbase, 7);
   //$fbase = scRegexReplace($fbase, "S[0-9][0-9]e[0-9][0-9]", $seasonepisode, 0);

   // TV Show filename Proper case (Soft. Preserves chars after sXXeXX.  For minor corrections)
   //$fbase = StrToLower($fbase);
   //$seasonepisode = scRegexExtract($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = scProperCase($fbase, 0);
   //$fbase = scRegexReplace($fbase, "S[0-9][0-9]e[0-9][0-9]", $seasonepisode, 0);

   // Movie filename cleanup
   //$fbase= scRegexReplaceGlobal($fbase, "_", " ", 0);
   //$fbase= scRegexReplaceGlobal($fbase, "\.", " ", 0);
   //$fbase = scRegexDelAfterMatch($fbase, " (hd|dvd|br)rip", 1);
   //$fbase= scRegexReplaceGlobal($fbase, " (hd|dvd|br)rip", "", 1);
   //$fbase = scProperCase($fbase, 0);

   return $fbase + $fext;
}
function scProperCase($strInput, $ignoreNfromend)
{
   @var $i = 1;
   @var $newStr;
   @var $len = StrLen($strInput);
   @var $nextchar;
   @var $capitaliseflag = 0;
   @var $tail = "";
   if ($ignoreNfromend > 0)
   {
      $tail = StrSub($strInput, $len - $ignoreNfromend, -1);
      $len = $len - $ignoreNfromend;
   }
   $newStr = "";
   $newStr = StrToUpper(StrSub($strInput, 0, 1));
   while($i < $len)
   {
      $nextchar = StrSub($strInput, $i, 1);
      if ($capitaliseflag == 1)
      {
         $newStr = $newStr + StrToUpper($nextchar);
         $capitaliseflag = 0;
      }
      else
      {
         $newStr = $newStr + $nextchar
      }
      $i = $i + 1;
      if (StrIsEqual($nextchar, " "))
      {
         $capitaliseflag = 1;
      }
   }
   return $newStr + $tail;
}
function scRegexExtract($strInput, $strRe, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexDelAfterMatch: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexDelAfterMatch: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexDelAfterMatch: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexDelAfterMatch: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexDelAfterMatch: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $result = $matchpart;
      //Log(0, 10, "....scRegexDelAfterMatch: replace complete, returning:" + $result);
   }
   return $result;
}
function scRegexDelAfterMatch($strInput, $strRe, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexDelAfterMatch: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexDelAfterMatch: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexDelAfterMatch: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexDelAfterMatch: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexDelAfterMatch: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $result = $firstpart + $matchpart;
      //Log(0, 10, "....scRegexDelAfterMatch: replace complete, returning:" + $result);
   }
   return $result;
}
function scReverse($strInput)
{
   @var $newStr;
   @var $len = StrLen($strInput) - 1;
   $newStr = "";
   while($len >= 0)
   {
      $newStr = $newStr + StrSub($strInput, $len, 1);
      $len = $len - 1;
   }
   return $newStr;
}
function scRegexReplaceGlobal($strInput, $strRe, $strRep, $nocase)
{
   @var $retstr;
   @var $maxloops = 20;
   @var $previousmatch = $strInput;
   @var $ismatch;
   $retstr = scRegexReplace($strInput, $strRe, $strRep, $nocase);
   $ismatch = StrIsEqual($retstr, $previousmatch);
   while (!$ismatch)
   {
      $previousmatch = $retstr;
      $maxloops = $maxloops - 1;
      if ($maxloops <= 0)
      {
         break;
      }
      $retstr = scRegexReplace($retstr, $strRe, $strRep, $nocase);
      $ismatch = StrIsEqual($retstr, $previousmatch);
   }
   return $retstr;
}
function scRegexReplace($strInput, $strRe, $strRep, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexReplace: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexReplace: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexReplace: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexReplace: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexReplace: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexReplace: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexReplace: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $lastpartidx = $matchpos + $matchlen;
      if ($lastpartidx < $inputlen)
      {
         $lastpart = StrSub($strInputOrig, $lastpartidx , -1);
      }
      else
      {
         $lastpart = "";
      }
      $result = $firstpart + $strRep + $lastpart;
      //Log(0, 10, "....scRegexReplace: replace complete, returning:" + $result);
   }
   return $result;
}
function main()
{
   Log(0, 10, "-------------- Script Start --------------" );
   @var $logprefix = "scMultiRename: ";
   @var $i;
   @var $filebase;
   @var $fileext;
   @var $resultsstr = "";
   @var $resultsarr[];
   @var $arrfullpath = GetSelectedPaths();
   @var $arr = GetSourceSelectedFileNames();
   @var $count = arrayCount($arr);
   if ($count == 0)
   {
      Log(0, 10, $logprefix + "no files selected, exiting");
   }
   else
   {   
      for($i = 0; $i < $count; $i++)
      {
         //Log(0, 10, $logprefix + "Full path:" + $arrfullpath[$i]);
         @var $dotpos = StrRegExpFind($arr[$i] , "\....$" );
         if ($dotpos == -1)
         {
            $filebase = $arr[$i];
            $fileext = "";
         }
         else
         {
            $filebase = StrSub($arr[$i], 0, $dotpos);
            $fileext = StrSub($arr[$i], $dotpos, -1);
         }
         arrayAdd($resultsarr, MakeNewName($filebase, $fileext));
         //Log(0, 10, $logprefix + "\"" + $arr[$i] + "\" --> " + $resultsarr);
         $resultsstr = $resultsstr + $arr[$i] + " -->\r\n" + $resultsarr[$i] + "\r\n";
      }
      @var $msganswer = MessageBox("Proceed with rename?", $resultsstr, 1);
      if ($msganswer == 1)
      {
         Log(0, 10, $logprefix + "[Ok] renaming...");
         for($i = 0; $i < $count; $i++)
         {
            @var $newname = $resultsarr[$i];
            Log(0, 10, $logprefix + "Renaming:[" + $arrfullpath[$i] + "] to [" + $newname + "]");
            MC.Filesystem.Rename FILE="{$arrfullpath[$i]}" NEWNAME='{$newname}'
         }
      }
      else
      {
         Log(0, 10, $logprefix + "[Cancel] not renaming...");
      }
   }
   Log(0, 10, "-------------- Script Done --------------" );
}
main();
« Last Edit: November 08, 2017, 01:18:18 by SpiroC »

Saavedra

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Rename file script
« Reply #1 on: February 01, 2018, 11:46:58 »
I have benefited from this content tremendously and I will publish it to spread the knowledge.



สโบเบ็ต
« Last Edit: October 17, 2018, 05:50:45 by Saavedra »

parcher

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Rename file script
« Reply #2 on: June 29, 2018, 20:10:36 »
Thanks for posting this script. I lack expertise with custom commands/scripts, but here's how I got it to work, for others like myself who lack experience:

1. Copy the code in SpiroC's post.
2. In the Menu click Configuration, the User Defined Commands.
3. Click the Create New Command button and give the command a name.
4. In the Command Type dropdown choose Multi-Script.
5. Paste the code in the box.
6. Click on Hotkey and choose a hotkey to run the script.
7. Click Save and Close

To use it highlight one or multiple files and then use the hotkey. It will rename the files by prepending the current date to the filename(s).

An improvement would be if a dialog box could pop up and I could customize the name, and have the option of completely replacing the filename.