Differences

This shows you the differences between the selected revisions of the page.

2016-09-29 2016-11-02
full -Format switch name (martin) making an extension out of this (martin)
Line 10: Line 10:
But for more advanced rename operations, you need to use your favorite scripting language language, like [[library_powershell|PowerShell]], to generate a new name and use [[library|WinSCP .NET assembly]] for the actual [[library_session_movefile|rename]] (or [[guide_automation#parametrized|generate a script file]]). But for more advanced rename operations, you need to use your favorite scripting language language, like [[library_powershell|PowerShell]], to generate a new name and use [[library|WinSCP .NET assembly]] for the actual [[library_session_movefile|rename]] (or [[guide_automation#parametrized|generate a script file]]).
-The following example prefixes all files in a specified directory with a timestamp in format ''YYYY-MM-DD-''.+The following example renames files using a regular expression. 
 + 
 +The script is distributed in WinSCP installer as a [[extension|WinSCP extension]]. 
 + 
 +<code powershell - BatchRename.ps1> 
 +# @name        Batch &Rename... 
 +# @command      powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" -sessionUrl &quot;!S" -remotePath "!/" -pattern "%Pattern%" -replacement "%Replacement%" -pause -sessionLogPath "%SessionLogPath%" %PreviewMode% !&  
 +# @description  Renames remote file using regular expression 
 +# @flag        RemoteFiles 
 +# @version      1 
 +# @homepage    ~~SELF~~ 
 +# @require      WinSCP 5.8.4 
 +# @option      - -run group "Rename" 
 +# @option        Pattern -run textbox "Replace file name part matching this pattern:" 
 +# @option        Replacement -run textbox "with:" 
 +# @option      - -run -config group "Options" 
 +# @option        PreviewMode -run -config checkbox "&Preview changes" "-previewMode" "-previewMode" 
 +# @option      - -config group "Logging" 
 +# @option        SessionLogPath -config sessionlogfile 
 +# @optionspage  ~~SELF~~#options
-<code powershell> 
param ( param (
-    # Use Generate URL function to obtain a value for -sessionUrl parameter.·+    # Use Generate URL function to obtain a value for -sessionUrl parameter.
    $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/",     $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/",
-    $remotePath = &quot;/path&quot;+    [Parameter(Mandatory = $True)] 
 +····$remotePath
 +    [Parameter(Mandatory = $True)] 
 +····$pattern, 
 +    $replacement, 
 +    [Switch] 
 +    $pause, 
 +    $sessionLogPath = $Null, 
 +    [Switch] 
 +    $previewMode, 
 +    [Parameter(Mandatory = $True, ValueFromRemainingArguments = $True, Position = 0)] 
 +    $files
) )
-·+
try try
{ {
-    # Load WinSCP .NET assembly +    if ($previewMode)
-    Add-Type -Path "WinSCPnet.dll" +
-  +
-    # Setup session options +
-    $sessionOptions = New-Object WinSCP.SessionOptions +
-    $sessionOptions.ParseUrl($sessionUrl) +
-  +
-    try+
    {     {
-        # Connect +        $anyChange = $False 
-        Write-Host "Connecting..." +        foreach ($file in $files)
-········$session = New-Object WinSCP.Session +
-········$session.Open($sessionOptions) +
-  +
-        # Retrieve file list +
-        Write-Host "Listing..." +
-        $files = $session.EnumerateRemoteFiles($remotePath, "*", [WinSCP.EnumerationOptions]::None) +
- +
-        Write-Host "Renaming..." +
- +
-        $timestampPrefix = $(Get-Date -Format "yyyy-MM-dd") + "-" +
- +
-        foreach ($fileInfo in $files)+
        {         {
-            $oldName = $fileInfo.Name +            $newName = $file -replace $pattern, $replacement 
-            $oldPath = $fileInfo.FullName +            Write-Host ("{0} => {1}&quot; -f $file, $newName
- ··········· +           if ($newName -ne $file
- ···········$newName = ($timestampPrefix + $oldName+           
-            $newPath = $session.CombinePaths($remotePath, $newName)+················$anyChange = $True 
 +············} 
 + ·······}
-············Write-Host ("{0} =&gt; {1}" -f $oldPath, $newPath+········Write-Host 
-            $session.MoveFile($oldPath, $newPath)+         
 +        if (!$anyChange) 
 +        { 
 +            Write-Host "No change to be made&quot; 
 +            $continue = $False 
 +········
 +       else 
 +········{ 
 +············Write-Host -NoNewline "Continue? y/N &quot
 + ···········$key = [System.Console]::ReadKey() 
 +            Write-Host 
 +            Write-Host 
 +            $continue = ($key.KeyChar -eq "y") 
 +            if (!$continue
 +           { 
 +················$pause = $False 
 +            }
        }         }
-  
-        Write-Host "Done" 
    }     }
-    finally+    else
    {     {
-        # Disconnect, clean up +        $continue = $True
-········$session.Dispose()+
    }     }
 +   
 +
 +    if (!$continue)
 +    {
 +        $result = 1
 +    }
 +    else
 +    {
 +        # Load WinSCP .NET assembly
 +        $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot }
 +        Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 +   
 +        # Setup session options
 +        $sessionOptions = New-Object WinSCP.SessionOptions
 +        $sessionOptions.ParseUrl($sessionUrl)
 +   
 +        $session = New-Object WinSCP.Session
-    exit 0+        try 
 +        { 
 +            $session.SessionLogPath = $sessionLogPath 
 +·     
 +            # Connect 
 +            $session.Open($sessionOptions) 
 + 
 +            foreach ($file in $files) 
 +            { 
 +                $newName = $file -replace $pattern, $replacement 
 +                Write-Host ("{0} => {1}" -f $file, $newName) 
 + 
 +                $fullName = $session.CombinePaths($remotePath, $file) 
 +                $fullNewName = $session.CombinePaths($remotePath, $newName) 
 +                $session.MoveFile($fullName, $fullNewName) 
 +            } 
 +        } 
 +        finally 
 +        { 
 +            # Disconnect, clean up 
 +            $session.Dispose() 
 +        } 
 + 
 +        & "$env:WINSCP_PATH\WinSCP.exe" "$sessionUrl" /refresh "$remotePath" 
 +    } 
 + 
 +    $result = 0
} }
catch [Exception] catch [Exception]
{ {
-    Write-Host ("Error: {0}" -f $_.Exception.Message) +    Write-Host $_.Exception.Message 
-    exit 1+    $result = 1
} }
 +
 +if ($pause)
 +{
 +    Write-Host "Press any key to exit..."
 +    [System.Console]::ReadKey() | Out-Null
 +}
 +
 +exit $result
</code> </code>
 +
 +==== Options ====
 +
 +&screenshotpict(extension_batch_rename)
 +
 +In the //"Replace file name part matching this pattern"// box, enter a [[wp>Regular_expression|regular expression]] pattern to look for in file name(s).
 +
 +In the //with// box, enter a replacement string to replace the file name part that matches the regular expression with. The replacement string can use ''$x'' syntax to refer to the ''x''-th group (subexpression in parentheses) captured by the pattern.
 +
 +On the image, you can see a pattern (''(\d{4})-(\d{2})-(\d{2})'') and a replacement string (''$2-$3-$1'') that change date stamp in file names from the ''yyyy-mm-dd'' format to the ''mm-dd-yyyy'' format by changing an order of captured groups.
 +
 +Check the //Preview changes// checkbox to see and confirm the changes in file names before actually renaming the files.
 +

Last modified: by martin