Differences

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

library_example_advanced_rename 2016-09-29 library_example_advanced_rename 2023-01-11 (current)
Line 7: Line 7:
  * changing leading characters: ''mv new*.* old*.*''   * changing leading characters: ''mv new*.* old*.*''
-===== Advanced rename with PowerShell =====+===== [[powershell]] Advanced rename with PowerShell =====
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;!E" -remotePath "!/" -pattern "%Pattern%" ^ 
 +#                  -replacement "%Replacement%" -refresh -pause -sessionLogPath "%SessionLogPath%" ^ 
 +#                  %PreviewMode% !&  
 +# @description  Renames remote files using a regular expression 
 +# @flag        RemoteFiles 
 +# @version      7 
 +# @homepage    ~~SELF~~ 
 +# @require      WinSCP 5.19 
 +# @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 Session 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-xxxxxxxxxxx...@example.com/", 
-    $remotePath = &quot;/path&quot;+    [Parameter(Mandatory = $True)] 
 +    $remotePath
 +    [Parameter(Mandatory = $True)] 
 +····$pattern
 +    $replacement, 
 +    [Switch] 
 +    $pause, 
 +    [Switch] 
 +    $refresh, 
 +    $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 &quot;Connecting..." +        foreach ($file in $files) 
- ·······$session = New-Object WinSCP.Session +········{ 
- ·······$session.Open($sessionOptions+ ···········$newName = $file -replace $pattern, $replacement 
-  +············if ($newName -eq $file
-········# Retrieve file list + ···········{ 
- ·······Write-Host "Listing...+ ···············Write-Host "$file not changed
- ·······$files = $session.EnumerateRemoteFiles($remotePath, "*", [WinSCP.EnumerationOptions]::None)+ ···········} 
 + ···········else 
 +············{ 
 +················Write-Host "$file => $newName" 
 + ···············$anyChange = $True 
 +············} 
 +········}
-        Write-Host "Renaming..."+        Write-Host
-        $timestampPrefix = $(Get-Date -Format "yyyy-MM-dd") + "-" +        if (!$anyChange)
- +
-        foreach ($fileInfo in $files)+
        {         {
-            $oldName = $fileInfo.Name +            Write-Host "No change to be made&quot; 
-            $oldPath = $fileInfo.FullName +            $continue = $False 
- ··········· +········} 
-            $newName = ($timestampPrefix + $oldName) +       else 
-            $newPath = $session.CombinePaths($remotePath, $newName+        { 
- +            Write-Host -NoNewline &quot;Continue? y/N &quot; 
-            Write-Host (&quot;{0} =&gt; {1}" -f $oldPath, $newPath+            $key = [System.Console]::ReadKey(
-            $session.MoveFile($oldPath, $newPath)+            Write-Host 
 +            Write-Host 
 + ···········$continue = ($key.KeyChar -eq &quot;y"
 + ···········if (!$continue
 +            { 
 +················$pause = $False 
 +            }
        }         }
-  
-        Write-Host "Done" 
    }     }
-    finally+    else
    {     {
-        # Disconnect, clean up +        $continue = $True
-········$session.Dispose()+
    }     }
-  + 
-    exit 0+   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 
 + 
 +        try 
 +        { 
 +            $session.SessionLogPath = $sessionLogPath 
 +     
 +            Write-Host "Connecting..." 
 +            $session.Open($sessionOptions) 
 + 
 +            Write-Host "Renaming..." 
 +            foreach ($file in $files) 
 +            { 
 +                $newName = $file -replace $pattern, $replacement 
 +                if ($newName -eq $file) 
 +                { 
 +                    Write-Host "$file not changed" 
 +                } 
 +                else 
 +                { 
 +                    Write-Host "$file => $newName" 
 +                    $fileMask = [WinSCP.RemotePath]::EscapeFileMask($file) 
 +                    $sourcePath = [WinSCP.RemotePath]::Combine($remotePath, $fileMask) 
 +                    $operationMask = [WinSCP.RemotePath]::EscapeOperationMask($newName) 
 +                    $targetPath = [WinSCP.RemotePath]::Combine($remotePath, $operationMask) 
 +                    $session.MoveFile($sourcePath, $targetPath) 
 +                } 
 +            } 
 +        } 
 +        finally 
 +        { 
 +            # Disconnect, clean up 
 +            $session.Dispose() 
 +        } 
 + 
 +        if ($refresh) 
 +        { 
 +            & "$env:WINSCP_PATH\WinSCP.exe" "$sessionUrl" /refresh "$remotePath" 
 +        } 
 +    } 
 + 
 +    $result = 0
} }
-catch [Exception]+catch
{ {
-    Write-Host ("Error: {0}" -f $_.Exception.Message) +    Write-Host "Error: $($_.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]] 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.
 +
 +In the //Session log file//, you can specify a path to a [[logging|session log file]]. The option is available on the [[ui_pref_commands|Preferences dialog]] only.
 +
 +In the //Keyboard shortcut//, you can specify a [[custom_key_shortcuts|keyboard shortcut]] for the extension. The option is available on the [[ui_pref_commands|Preferences dialog]] only.
 +

Last modified: by martin