【问题标题】:PowerShell FINDSTR eqivalent?PowerShell FINDSTR 等价物?
【发布时间】:2010-09-06 02:16:59
【问题描述】:

PowerShell 的 DOS FINDSTR 等效项是什么?我需要在一堆日志文件中搜索“错误”。

【问题讨论】:

标签: search powershell


【解决方案1】:

这里是快速回答

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

我发现它here 有一个非常深入的答案!

【讨论】:

    【解决方案2】:

    例如,在该目录及其所有子目录的c文件中查找“#include”的所有实例。

    gci -r -i *.c | select-string "#include"
    

    gci 是 get-childitem 的别名

    【讨论】:

      【解决方案3】:

      只是为了扩展 Monroecheeseman 的答案。 gci 是 Get-ChildItem 的别名(相当于 dir 或 ls),-r 开关执行递归搜索,-i 表示包含。

      将该查询的结果通过管道传输到 select-string 使其读取每个文件并查找与正则表达式匹配的行(在这种情况下提供的行是 ERROR,但它可以是任何 .NET 正则表达式)。

      结果将是匹配对象的集合,显示行匹配、文件和其他相关信息。

      【讨论】:

        【解决方案4】:
        if ($entry.EntryType -eq "Error")
        

        由于是面向对象的,您希望使用您可以找到here 的标准比较运算符之一来测试有问题的属性。

        我现在有一个 PS script 为我远程监视日志 - 一些简单的修改应该可以为你工作。

        编辑:如果您不想像我一样展开,我想我还应该添加一个已经为此构建的 cmdlet。签出:

        man Get-EventLog
        Get-EventLog -newest 5 -logname System -EntryType Error
        

        【讨论】:

          【解决方案5】:

          在相关说明中,这里的搜索将列出包含特定正则表达式搜索或字符串的所有文件。它可以使用一些改进,所以请随意工作。此外,如果有人想将它封装在一个受欢迎的函数中。

          我是新来的,所以如果这应该进入它自己的主题,请告诉我。我想我会把它放在她身上,因为这看起来很相关。

          # Search in Files Script
          # ---- Set these before you begin ---- 
          $FolderToSearch="C:\" # UNC paths are ok, but remember you're mass reading file contents over the network
          $Search="Looking For This" # accepts regex format
          $IncludeSubfolders=$True #BUG: if this is set $False then $FileIncludeFilter must be "*" or you will always get 0 results
          $AllMatches=$False
          $FileIncludeFilter="*".split(",") # Restricting to specific file types is faster than excluding everything else
          $FileExcludeFilter="*.exe,*.dll,*.wav,*.mp3,*.gif,*.jpg,*.png,*.ghs,*.rar,*.iso,*.zip,*.vmdk,*.dat,*.pst,*.gho".split(",")
          
          # ---- Initialize ----
          if ($AllMatches -eq $True) {$SelectParam=@{AllMatches=$True}}
          else {$SelectParam=@{List=$True}}
          if ($IncludeSubfolders -eq $True) {$RecurseParam=@{Recurse=$True}}
          else {$RecurseParam=@{Recurse=$False}}
          
          # ---- Build File List ---- 
          #$Files=Get-Content -Path="$env:userprofile\Desktop\FileList.txt" # For searching a manual list of files
          Write-Host "Building file list..." -NoNewline
          $Files=Get-ChildItem -Include $FileIncludeFilter -Exclude $FileExcludeFilter -Path $FolderToSearch -ErrorAction silentlycontinue @RecurseParam|Where-Object{-not $_.psIsContainer} # @RecurseParam is basically -Recurse=[$True|$False]
          #$Files=$Files|Out-GridView -PassThru -Title 'Select the Files to Search' # Manually choose files to search, requires powershell 3.0
          Write-Host "Done"
          
          # ---- Begin Search ---- 
          Write-Host "Searching Files..."
          $Files|
              Select-String $Search @SelectParam| #The @ instead of $ lets me pass the hastable as a list of parameters.  @SelectParam is either -List or -AllMatches
              Tee-Object -Variable Results|
              Select-Object Path
          Write-Host "Search Complete"
          #$Results|Group-Object path|ForEach-Object{$path=$_.name; $matches=$_.group|%{[string]::join("`t", $_.Matches)}; "$path`t$matches"} # Show results including the matches separated by tabs (useful if using regex search)
          
          <# Other Stuff
              #-- Saving and restoring results
              $Results|Export-Csv "$env:appdata\SearchResults.txt" # $env:appdata can be replaced with any UNC path, this just seemed like a logical place to default to
              $Results=Import-Csv "$env:appdata\SearchResults.txt"
          
              #-- alternate search patterns
              $Search="(\d[-|]{0,}){15,19}" #Rough CC Match
          #>
          

          【讨论】:

            【解决方案6】:

            这不是最好的方法:

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

            这帮助我找到了所有包含 | 字符的 csv 文件。

            【讨论】:

              【解决方案7】:

              PowerShell 基本上排除了对 findstr.exe 的需求,正如前面的答案所示。这些答案中的任何一个都应该可以正常工作。

              但是,如果您确实需要使用 findstr.exe(就像我的情况),这里有一个 PowerShell 包装器:

              使用-Verbose 选项输出findstr 命令行。


              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 $_
                          }
                      }
                  }
              }
              

              【讨论】:

                【解决方案8】:

                仅供参考: 如果您更新到 Powershell 版本 7,您可以使用 grep ... 我知道 egrep 在 Azure CLI 的 powershell 中... 但是SS在那里! 这里有一篇旧文章:[https://devblogs.microsoft.com/powershell/select-string-and-grep/]

                【讨论】:

                  猜你喜欢
                  • 2015-03-30
                  • 2011-09-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-07-25
                  • 2011-07-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多