PowerShell equivalente a grep -f


157

Estoy buscando el equivalente de PowerShell grep --file=filename. Si no sabesgrep , el nombre de archivo es un archivo de texto donde cada línea tiene un patrón de expresión regular que desea hacer coincidir.

Tal vez me estoy perdiendo algo obvio, pero Select-Stringno parece tener esta opción.

Respuestas:


178

El -Patternparámetro en Select-Stringadmite una variedad de patrones. Entonces el que estás buscando es:

Get-Content .\doc.txt | Select-String -Pattern (Get-Content .\regex.txt)

Esto busca a través del archivo doc.txtde texto usando cada expresión regular (una por línea) enregex.txt


66
Además, la finalización de la pestaña de PowerShell hará que los comandos se capitalicen correctamente, por lo que no es difícil de ingresar.
joon

3
@joon Un par de años tarde, pero agregaría que Powershell no distingue entre mayúsculas y minúsculas, por lo que la capitalización de comandos no es un problema.
dee-see

1
@Vache, por supuesto, creo que mi comentario anterior es una respuesta a otro comentario, pero parece que el comentario ya no está.
joon

85
PS) new-alias grep findstr
PS) C:\WINDOWS> ls | grep -I -N exe

105:-a---        2006-11-02     13:34      49680 twunk_16.exe
106:-a---        2006-11-02     13:34      31232 twunk_32.exe
109:-a---        2006-09-18     23:43     256192 winhelp.exe
110:-a---        2006-11-02     10:45       9216 winhlp32.exe

PS) grep /?

17
Nunca entendí cómo esto obtuvo tantos votos. Ni siquiera responde la pregunta ...
Frode F.

18
Lo que me gusta de esta respuesta es que findstrfunciona más como grepen Linux. Select-Stringes ideal para trabajar con objetos, pero a veces solo quieres unir cadenas.
Elijah W. Gagne

77
Vale la pena señalar que findstrno es nativo de PowerShell, sino símbolo del sistema.
anishpatel

1
Este comando findtr ya estaba disponible para mí, y funcionó como unix GREP.
Lennon

37

No estoy familiarizado con grep, pero con Select-String puedes hacer:

Get-ChildItem filename.txt | Select-String -Pattern <regexPattern>

También puede hacerlo con Get-Content:

(Get-Content filename.txt) -match 'pattern'

44
Extendió esto a, por ejemplo dir *.cs -Recurse | sls "TODO" | select -Unique "Path". Gracias por el excelente puntero.
Jeroen

4

Así que encontré una respuesta bastante buena en este enlace: https://www.thomasmaurer.ch/2011/03/powershell-search-for-string-or-grep-for-powershell/

Pero esencialmente es:

Select-String -Path "C:\file\Path\*.txt" -Pattern "^Enter REGEX Here$"

Esto proporciona una búsqueda de archivos de directorio (* o simplemente puede especificar un archivo) y una búsqueda de contenido de archivos, todo en una línea de PowerShell, muy similar a grep. La salida será similar a:

doc.txt:31: Enter REGEX Here
HelloWorld.txt:13: Enter REGEX Here

1
Quiere cargar el patrón desde un archivo.
Brian Gordon

2

Esta pregunta ya tiene una respuesta, pero solo quiero agregar que en Windows existe el Subsistema de Windows para Linux WSL .

Entonces, por ejemplo, si desea verificar si tiene un servicio llamado Elasicsearch que está en ejecución , puede hacer algo como el fragmento a continuación en PowerShell

net start | grep Elasticsearch


2

Tuve el mismo problema al tratar de encontrar texto en archivos con powershell. Usé lo siguiente: permanecer lo más cerca posible del entorno Linux.

Esperemos que esto ayude a alguien:

Potencia Shell:

PS) new-alias grep findstr
PS) ls -r *.txt | cat | grep "some random string"

Explicación:

ls       - lists all files
-r       - recursively (in all files and folders and subfolders)
*.txt    - only .txt files
|        - pipe the (ls) results to next command (cat)
cat      - show contents of files comming from (ls)
|        - pipe the (cat) results to next command (grep)
grep     - search contents from (cat) for "some random string" (alias to findstr)

Sí, esto también funciona:

PS) ls -r *.txt | cat | findstr "some random string"

0

pero select-String no parece tener esta opción.

Correcto. PowerShell no es un clon del conjunto de herramientas de * nix shells.

Sin embargo, no es difícil construir algo así:

$regexes = Get-Content RegexFile.txt | 
           Foreach-Object { new-object System.Text.RegularExpressions.Regex $_ }

$fileList | Get-Content | Where-Object {
  foreach ($r in $regexes) {
    if ($r.IsMatch($_)) {
      $true
      break
    }
  }
  $false
}

Esta es una mala respuesta. Select-String -Pattern somestringestá mucho más limpio
Kolob Canyon

0

¿Tal vez?

[regex]$regex = (get-content <regex file> |
foreach {
          '(?:{0})' -f $_
        }) -join '|'

Get-Content <filespec> -ReadCount 10000 |
 foreach {
           if ($_ -match $regex)
             {
              $true
              break
             }
         }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.