Search recursively for text in remote directory / Grep files over SFTP/FTP protocol
The following script uses WinSCP .NET assembly from a PowerShell script. If you have another preferred language, you can easily translate it.
The script is distributed in WinSCP installer as a WinSCP extension.
To run the script manually use:
powershell.exe -File SearchText.ps1 -sessionUrl "sftp://username:password;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/" -path "/path" -text "text"
Advertisement
See also Listing files matching wildcard.
You can alter the script for other tasks, instead of grepping the matching files. You can for example remove or download the matching files. Just modify the action in the Action on match
block accordingly.
# @name &Search for Text... # @command powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" ^ # -sessionUrl "!E" -path "!/" -text "%Text%" -wildcard "%Wildcard%" ^ # -pause -sessionLogPath "%SessionLogPath%" # @description Searches recursively for a text in the current remote directory # @version 7 # @homepage https://winscp.net/eng/docs/library_example_recursive_search_text # @require WinSCP 5.16 # @option Text -run textbox "Text:" # @option Wildcard -run textbox "File mask:" "*.*" # @option SessionLogPath -config sessionlogfile # @optionspage https://winscp.net/eng/docs/library_example_recursive_search_text#options param ( # Use Generate Session URL function to obtain a value for -sessionUrl parameter. $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/", [Parameter(Mandatory = $True)] $path, [Parameter(Mandatory = $True)] $text, $wildcard = "*.*", $sessionLogPath = $Null, [Switch] $pause ) try { if (!$text) { throw "No Text was specified." } # 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 # Connect $session.Open($sessionOptions) # Recursivelly enumerate files to grep $fileInfos = $session.EnumerateRemoteFiles( $path, $wildcard, [WinSCP.EnumerationOptions]::AllDirectories) foreach ($fileInfo in $fileInfos) { # Action on match # Modify the code below if you want to do another task with # matching files, instead of grepping their contents Write-Host "File $($fileInfo.FullName) matches mask, searching contents..." $tempPath = (Join-Path $env:temp $fileInfo.Name) # Download file to temporary directory $filePath = [WinSCP.RemotePath]::EscapeFileMask($fileInfo.FullName) $transferResult = $session.GetFiles($filePath, $tempPath) # Did the download succeeded? if (!$transferResult.IsSuccess) { # Print error (but continue with other files) Write-Host $transferResult.Failures[0].Message } else { # Search and print lines containing "text". # Use -Pattern instead of -SimpleMatch for regex search $matchInfo = Select-String -Path $tempPath -SimpleMatch $text # Print the results foreach ($match in $matchInfo) { Write-Host ($fileInfo.FullName + ":" + $match.LineNumber + ":" + $match.Line) } # Delete temporary local copy Remove-Item $tempPath } } } finally { # Disconnect, clean up $session.Dispose() } $result = 0 } catch { Write-Host "Error: $($_.Exception.Message)" $result = 1 } # Pause if -pause switch was used if ($pause) { Write-Host "Press any key to exit..." [System.Console]::ReadKey() | Out-Null } exit $result
Advertisement
Options
In the Text box, specify the text to look for. The option is available when executing the extension only.
In the File mask box, specify a file mask to select files. The option is available when executing the extension only.
In the Session log file, you can specify a path to a session log file. The option is available on the Preferences dialog only.
In the Keyboard shortcut, you can specify a keyboard shortcut for the extension. The option is available on the Preferences dialog only.