2009-09-28 28 views

Respuesta

10

Hay dos problemas. Como en la pregunta, select-string necesita operar en la cadena de salida, que se puede obtener desde "out-string". Además, select-string no funciona linewise en las cadenas que están conectadas a él. Aquí hay una solución genérica

(alias|out-string) -split "`n" | select-string Write 
+3

En Powershell 1.0 no hay división. Puede hacer esto en su lugar: (alias | out-string -stream) | select-string Write – Mike

+1

¿No les falta completamente el punto aquí? No es necesario que grep la salida de PowerShell. – x0n

+2

@ x0n Bueno, hay casos en los que cuando estoy buscando rápidamente algo a través de la consola PS y no sé y/o me importa si se trata de una propiedad particular. Me resulta demasiado tedioso usar 'Get-Member' y luego usar la propiedad y la expresión correctas en el comando' where'. Y 'grep' es particularmente bueno en este caso. – OnesimusUnbound

22

Su problema es que alias emite una secuencia de objetos AliasInfo, en lugar de una secuencia de cadenas . Esto hace lo que creo que quieres.

alias | out-string -stream | select-string Alias 

o como una función

function grep { 
    $input | out-string -stream | select-string $args 
} 

alias | grep Alias 

Cuando no se manejan las cosas que están en la tubería (como cuando se acaba de ejecutar 'alias'), el shell sabe utilizar el ToString () método en cada objeto (o utilice los formatos de salida especificados en la información ETS).

+0

Solo quería agregar que esto funciona en la salida de un programa cli genérico. Se asemeja a Linux ./foo | grep bar como yo quería – Sint

27

Si realmente quiere "grep" la salida formateada (cadenas de visualización), entonces vaya con el enfoque de Mike. Definitivamente hay momentos en que esto es útil. Sin embargo, si quiere intentar abarcar la naturaleza de la tubería de objetos de PowerShell, intente esto. En primer lugar, echa un vistazo a las propiedades de los objetos que fluyen a través de la canalización:

PS> alias | Get-Member 


    TypeName: System.Management.Automation.AliasInfo 

Name    MemberType  Definition 
----    ----------  ---------- 
Equals    Method   bool Equals(System.Object obj) 
GetHashCode   Method   int GetHashCode() 
GetType    Method   type GetType() 
ToString   Method   string ToString() 
<snip> 
*Definition*  Property  System.String Definition {get;} 
<snip> 

Nota la propiedad Definición que es una cabecera que se ve cuando se muestra el resultado de Get-Alias ​​(alias) por ejemplo:

PS> alias 

CommandType  Name   *Definition* 
-----------  ----   ---------- 
Alias   %    ForEach-Object 
<snip> 

Por lo general, el título del encabezado coincide con el nombre de la propiedad, pero no siempre. Ahí es donde usar Get-Member es útil. Le muestra lo que necesita para "guiar" en contra. Ahora, si lo que desea "grep" es el contenido de la propiedad Definition, considere esto. En lugar de simplemente grepping valor que la propiedad de uno, en su lugar puede filtrar cada objeto AliasInfo en el pipepline por los contenidos de esta propiedad y se puede utilizar una expresión regular para hacerlo, por ejemplo:

PS> alias | Where-Object {$_.Definition -match 'alias'} 

CommandType  Name     Definition 
-----------  ----     ---------- 
Alias   epal     Export-Alias 
Alias   gal     Get-Alias 
Alias   ipal     Import-Alias 
Alias   nal     New-Alias 
Alias   sal     Set-Alias 

En este ejemplo utilizo el caso -Objeto cmdlet para filtrar objetos en función de algún script arbitrario. En este caso, filtre por la propiedad Defintion que coincida con el 'alias' de expresiones regulares. Solo aquellos objetos que devuelven verdadero para ese filtro pueden propagarse por la canalización y formatearse para mostrarse en el host.

BTW si está escribiendo esto, entonces puede usar uno de los dos alias para Where-Object - 'Where' o '?'.Por ejemplo:

PS> gal | ?{$_.Definition -match '-Item*'} 
+4

También puede usar 'findstr' donde PowerShell manejará la conversión a texto, ya que no es un cmdlet sino un programa (simplemente no está completo, en general siempre es mejor filtrar de acuerdo con las propiedades, imho :-)) – Joey

+0

FYI , según Powershell 3, el siguiente es más conciso: 'gal | Donde Definición -match 'alias'' – tkokasih

+0

Siento que esto responde al contenido OP, pero no al título. Si mi comando es (por ejemplo) "congelación de pip", el resultado es solo texto. La respuesta de Roi es lo que parece significar el título de esto. –

4

La solución propuesta es sólo para mucho trabajo por algo que se pueda hacer de esta manera:

Get-Alias -Definition Write* 
24

Creo que esta solución es más fácil y mejor, utilizar directamente el findstr función:

alias | findstr -i Write 

también puede crear un alias para utilizar la palabra grep:

new-alias grep findstr 
+0

Este es el enfoque más intuitivo y fácil de recordar entre todas las otras respuestas. –

0

Para una solución más flexible y perezosa, puede hacer coincidir todas las propiedades de los objetos. La mayoría de las veces, esto debería obtener el comportamiento que desea, y siempre puede ser más específico cuando no lo hace. Aquí hay una función grep que funciona según este principio:

Function Select-ObjectPropertyValues { 
    param(
    [Parameter(Mandatory=$true,Position=0)] 
    [String] 
    $Pattern, 
    [Parameter(ValueFromPipeline)] 
    $input) 

    $input | Where-Object {($_.PSObject.Properties | Where-Object {$_.Value -match $Pattern} | Measure-Object).count -gt 0} | Write-Output 
} 
Cuestiones relacionadas