PowerShell FINDSTR eqivalent?

后端 未结 8 936
栀梦
栀梦 2021-02-02 09:28

What\'s the DOS FINDSTR equivalent for PowerShell? I need to search a bunch of log files for \"ERROR\".

相关标签:
8条回答
  • 2021-02-02 09:39

    FYI: If you update to Powershell version 7 you can use grep... I know egrep is in powershell on Azure CLI... But SS is there! An old article here: [https://devblogs.microsoft.com/powershell/select-string-and-grep/]

    0 讨论(0)
  • 2021-02-02 09:43

    Here's the quick answer

    Get-ChildItem -Recurse -Include *.log | select-string ERROR 
    

    I found it here which has a great indepth answer!

    0 讨论(0)
  • 2021-02-02 09:43

    PowerShell has basically precluded the need for findstr.exe as the previous answers demonstrate. Any of these answers should work fine.

    However, if you actually need to use findstr.exe (as was my case) here is a PowerShell wrapper for it:

    Use the -Verbose option to output the findstr command line.


    function Find-String
    {
        [CmdletBinding(DefaultParameterSetName='Path')]
        param
        (
            [Parameter(Mandatory=$true, Position=0)]
            [string]
            $Pattern,
    
            [Parameter(ParameterSetName='Path', Mandatory=$false, Position=1, ValueFromPipeline=$true)]
            [string[]]
            $Path,
    
            [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
            [Alias('PSPath')]
            [string[]]
            $LiteralPath,
    
            [Parameter(Mandatory=$false)]
            [switch]
            $IgnoreCase,
    
            [Parameter(Mandatory=$false)]
            [switch]
            $UseLiteral,
    
            [Parameter(Mandatory=$false)]
            [switch]
            $Recurse,
    
            [Parameter(Mandatory=$false)]
            [switch]
            $Force,
    
            [Parameter(Mandatory=$false)]
            [switch]
            $AsCustomObject
        )
    
        begin
        {
            $value = $Pattern.Replace('\', '\\\\').Replace('"', '\"')
    
            $findStrArgs = @(
                '/N'
                '/O'
                @('/R', '/L')[[bool]$UseLiteral]
                "/c:$value"
            )
    
            if ($IgnoreCase)
            {
                $findStrArgs += '/I'
            }
    
            function GetCmdLine([array]$argList)
            {
                ($argList | foreach { @($_, "`"$_`"")[($_.Trim() -match '\s')] }) -join ' '
            }
        }
    
        process
        {
            $PSBoundParameters[$PSCmdlet.ParameterSetName] | foreach {
                try
                {
                    $_ | Get-ChildItem -Recurse:$Recurse -Force:$Force -ErrorAction Stop | foreach {
                        try
                        {
                            $file = $_
                            $argList = $findStrArgs + $file.FullName
    
                            Write-Verbose "findstr.exe $(GetCmdLine $argList)"
    
                            findstr.exe $argList | foreach {
                                if (-not $AsCustomObject)
                                {
                                    return "${file}:$_"
                                }
    
                                $split = $_.Split(':', 3)
    
                                [pscustomobject] @{
                                    File = $file
                                    Line = $split[0]
                                    Column = $split[1]
                                    Value = $split[2]
                                }
                            }
                        }
                        catch
                        {
                            Write-Error -ErrorRecord $_
                        }
                    }
                }
                catch
                {
                    Write-Error -ErrorRecord $_
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-02 09:47

    Just to expand on Monroecheeseman's answer. gci is an alias for Get-ChildItem (which is the equivalent to dir or ls), the -r switch does a recursive search and -i means include.

    Piping the result of that query to select-string has it read each file and look for lines matching a regular expression (the provided one in this case is ERROR, but it can be any .NET regular expression).

    The result will be a collection of match objects, showing the line matching, the file, and and other related information.

    0 讨论(0)
  • 2021-02-02 09:53

    This is not the best way to do this:

    gci <the_directory_path> -filter *.csv | where { $_.OpenText().ReadToEnd().Contains("|") -eq $true }
    

    This helped me find all csv files which had the | character in them.

    0 讨论(0)
  • 2021-02-02 09:54
    if ($entry.EntryType -eq "Error")
    

    Being Object Oriented, you want to test the property in question with one of the standard comparison operators you can find here.

    I have a PS script watching logs remotely for me right now - some simple modification should make it work for you.

    edit: I suppose I should also add that is a cmdlet built for this already if you don't want to unroll the way I did. Check out:

    man Get-EventLog
    Get-EventLog -newest 5 -logname System -EntryType Error
    
    0 讨论(0)
提交回复
热议问题