2008-08-18 9 views
19

¿Cuál es el equivalente de DOS FINDSTR para PowerShell? Necesito buscar un montón de archivos de registro para "ERROR".PowerShell FINDSTR eqivalent?

+1

Hay un sitio web con un buen artículo para esto: http://www.interact-sw.co.uk/iangblog/2006/06/03/pshfindstr –

Respuesta

23

Aquí está la respuesta rápida

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

lo encontré here que tiene una gran respuesta en profundidad!

0
if ($entry.EntryType -eq "Error") 

Al estar orientado a objetos, que desea probar la propiedad en cuestión con uno de los operadores de comparación estándar se pueden encontrar here.

Tengo un PS script viendo registros de forma remota para mí en este momento - algunas modificaciones simples deberían hacer que funcione para usted.

editar: Supongo que también debería agregar que ya se trata de un cmdlet creado para esto si no desea desenrollarlo de la manera en que lo hice. Salida:

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

Por ejemplo, encontrar todas las instancias de "# include" en los archivos de C en este directorio y todos los subdirectorios.

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

GCI es un alias para conseguir-childitem

3

Sólo para ampliar la respuesta de Monroecheeseman. gci es un alias para Get-ChildItem (que es el equivalente a dir o ls), el modificador -r realiza una búsqueda recursiva y -i means include.

Canalizando el resultado de esa consulta a select-string hace que lea cada archivo y busque líneas que coincidan con una expresión regular (la proporcionada en este caso es ERROR, pero puede ser cualquier expresión regular .NET).

El resultado será una colección de objetos coincidentes, mostrando la coincidencia de línea, el archivo y otra información relacionada.

0

En una nota relacionada, aquí hay una búsqueda que enumerará todos los archivos que contienen una búsqueda de expresiones regulares o una cadena en particular. Podría usar alguna mejora así que siéntete libre de trabajar en ello. Además, si alguien quisiera encapsularlo en una función que sería bienvenida.

Soy nuevo aquí, así que si esto debe ir en su propio tema házmelo saber. Pensé que lo pondría, ya que esto se ve principalmente relacionado.

# 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) {[email protected]{AllMatches=$True}} 
else {[email protected]{List=$True}} 
if ($IncludeSubfolders -eq $True) {[email protected]{Recurse=$True}} 
else {[email protected]{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 
#> 
0

Ésta no es la mejor manera de hacer esto:

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

Esto me ayudó a encontrar todos los archivos CSV que tenían el carácter | en ellos.

0

PowerShell básicamente ha impedido la necesidad de findstr.exe como lo demuestran las respuestas anteriores. Cualquiera de estas respuestas debería funcionar bien.

Sin embargo, si realmente necesita usar findstr.exe (como era mi caso) que aquí hay una envoltura de PowerShell para ello:

Utilice la opción -Verbose a la salida de la línea de comandos 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 $_ 
      } 
     } 
    } 
} 
Cuestiones relacionadas