This is an old revision of the document!

Search recursively for text in remote directory / Grep files over SFTP/FTP protocol

The following example uses WinSCP .NET assembly from a PowerShell script. If you have another preferred language, you can easily translate it.

You can run the script (e.g. search.ps1) from WinSCP GUI using local custom command:

powershell.exe -File search.ps1 -path "!/" -text !?Text:?!

Advertisement

See also Listing files matching wildcard.

param (
    [Parameter(Mandatory)]
    $path,
    [Parameter(Mandatory)]
    $text,
    $wildcard = "*.*"
)
 
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)
            {
                Write-Host ("File {0} matches mask, searching contents..." -f $filePath)
                $tempPath = ($env:temp + "\" + $fileInfo.Name)
                # Download file to temporary directory
                $transferResult = $session.GetFiles($filePath, $tempPath)
                # Did the download succeded?
                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.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
    
    try
    {
        # Connect
        $session.Open($sessionOptions)
        
        # Start recursive search
        SearchDirectory $session $path $wildcard $text
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Advertisement

Last modified: by martin