Differences
This shows you the differences between the selected revisions of the page.
| 2016-06-07 | 2016-07-29 | ||
| sessionlogfile alias (martin) | 5.9 stable released (martin) | ||
| Line 1: | Line 1: | ||
| ====== Search recursively for text in remote directory / Grep files over SFTP/FTP protocol ====== | ====== Search recursively for text in remote directory / Grep files over SFTP/FTP protocol ====== | ||
| - | The following example uses [[library|WinSCP .NET assembly]] from a [[library_powershell|PowerShell]] script. If you have another preferred language, you can easily translate it. | + | The following script uses [[library|WinSCP .NET assembly]] from a [[library_powershell|PowerShell]] script. If you have another preferred language, you can easily translate it. |
| - | //In the latest beta version//, the example is distributed in WinSCP installer as a [[extension|WinSCP extension]]. &beta | + | The script is distributed in WinSCP installer as a [[extension|WinSCP extension]]. |
| - | You can run the script (e.g. ''SearchText.ps1'') from WinSCP GUI using [[guide_custom_commands_automation|local custom command]]: | + | To run the script manually use: |
| <code> | <code> | ||
| - | powershell.exe -File SearchText.ps1 -sessionUrl "!S" -path "!/" -text "!?Text:?!" -pause | + | powershell.exe -File SearchText.ps1 -path "/path" -text "text" |
| </code> | </code> | ||
| Line 14: | Line 14: | ||
| You can alter the script for other tasks, instead of grepping the matching files. You can for example [[library_session_removefiles|remove]] or [[library_session_getfiles|download]] the matching files. Just modify the action in the ''Action on match'' block accordingly. | You can alter the script for other tasks, instead of grepping the matching files. You can for example [[library_session_removefiles|remove]] or [[library_session_getfiles|download]] the matching files. Just modify the action in the ''Action on match'' block accordingly. | ||
| - | |||
| - | ===== In the Beta Version ===== | ||
| - | In the latest beta version, you can simplify the implementation by using ''[[library_session_enumerateremotefiles|Session.EnumerateRemoteFiles]]''. &beta | ||
| <code powershell - SearchText.ps1> | <code powershell - SearchText.ps1> | ||
| Line 123: | Line 120: | ||
| </code> | </code> | ||
| - | ==== Options ==== | + | ===== Options ===== |
| In the //Text// box, specify the text to look for. The option is available when executing the extension only. | In the //Text// box, specify the text to look for. The option is available when executing the extension only. | ||
| Line 131: | Line 128: | ||
| 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 //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 Stable Version ===== | ||
| - | <code powershell> | ||
| - | param ( | ||
| - | # Use Generate URL function to obtain a value for -sessionUrl parameter. | ||
| - | $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/", | ||
| - | [Parameter(Mandatory)] | ||
| - | $path, | ||
| - | [Parameter(Mandatory)] | ||
| - | $text, | ||
| - | $wildcard = "*.*", | ||
| - | [Switch] | ||
| - | $pause = $False | ||
| - | ) | ||
| - | |||
| - | function SearchDirectory ($session, $path, $wildcard, $text) | ||
| - | { | ||
| - | Write-Host ("Searching directory {0} ..." -f $path) | ||
| - | |||
| - | $directoryInfo = $session.ListDirectory($path) | ||
| - | |||
| - | foreach ($fileInfo in $directoryInfo.Files) | ||
| - | { | ||
| - | $filePath = ($path + "/" + $fileInfo.Name) | ||
| - | |||
| - | if ($fileInfo.IsDirectory) | ||
| - | { | ||
| - | # Skip references to current and parent directories | ||
| - | if (($fileInfo.Name -ne ".") -and | ||
| - | ($fileInfo.Name -ne "..")) | ||
| - | { | ||
| - | # Recurse into subdirectory | ||
| - | SearchDirectory $session $filePath $wildcard $text | ||
| - | } | ||
| - | } | ||
| - | else | ||
| - | { | ||
| - | # Does file name match wildcard? | ||
| - | if ($fileInfo.Name -Like $wildcard) | ||
| - | { | ||
| - | # 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 {0} matches mask, searching contents..." -f $filePath) | ||
| - | $tempPath = ($env:temp + "\" + $fileInfo.Name) | ||
| - | # Download file to temporary directory | ||
| - | $transferResult = $session.GetFiles($session.EscapeFileMask($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 ($filePath + ":" + $match.LineNumber + ":" + $match.Line) | ||
| - | } | ||
| - | # Delete temporary local copy | ||
| - | Remove-Item $tempPath | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | |||
| - | try | ||
| - | { | ||
| - | # Load WinSCP .NET assembly | ||
| - | Add-Type -Path "WinSCPnet.dll" | ||
| - | |||
| - | # Setup session options | ||
| - | $sessionOptions = New-Object WinSCP.SessionOptions | ||
| - | $sessionOptions.ParseUrl($sessionUrl) | ||
| - | |||
| - | $session = New-Object WinSCP.Session | ||
| - | |||
| - | try | ||
| - | { | ||
| - | # Connect | ||
| - | $session.Open($sessionOptions) | ||
| - | |||
| - | # Start recursive search | ||
| - | SearchDirectory $session $path $wildcard $text | ||
| - | } | ||
| - | finally | ||
| - | { | ||
| - | # Disconnect, clean up | ||
| - | $session.Dispose() | ||
| - | } | ||
| - | |||
| - | $result = 0 | ||
| - | } | ||
| - | catch [Exception] | ||
| - | { | ||
| - | Write-Host ("Error: {0}" -f $_.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 | ||
| - | </code> | ||