2009-09-30 6 views
15

Sto usando PowerShell per "grep" il mio codice sorgente per una stringa particolare. Se la stringa è nel file, mi piacerebbe il nome del file, non la riga di codice che contiene la stringa.nome file di output, non stringa con select-string

Vorrei anche il nome del file, solo una volta, non elencato per tutte le volte che il file esiste.

Attualmente sto usando:

gci . -include "*.sql" -recurse | select-string -pattern 'someInterestingString' 

ora ho capito che l'uscita di select-string è una sorta di Ojbect, e quello che sto vedendo nella console è, io sto cercando di indovinare, il ToString() di quell'oggetto. Presumo che potrei usare format-table per controllare l'output della stringa di selezione e suppongo che sort ottenga solo valori distinti.

ma questo è un sacco di ipotesi.

risposta

32

Non credo di capire completamente cosa stai cercando di fare. Se si desidera che l'output raggruppati per file, è possibile reindirizzare in Format-Table con il parametro -GroupBy:

gci . -include "*.sql" -recurse ` 
    | select-string -pattern 'someInterestingString' ` 
    | Format-Table -GroupBy Path 

Se si desidera ottenere solo i nomi dei file che corrispondono, senza qualsiasi altra informazione, è possibile utilizzare Select-Object con la -Unique parametro:

gci . -include "*.sql" -recurse ` 
    | select-string -pattern 'someInterestingString' ` 
    | Select-Object -Unique Path 

Se siete interessati a solo il nome del file, indipendentemente dal fatto che il nome stesso appare più volte nella gerarchia, quindi è possibile selezionare invece la proprietà Filename.


Nota: La Get-Member cmdlet è un grande aiuto per capire cosa esistono proprietà di un oggetto:

gci . -include "*.sql" -recurse ` 
    | select-string -pattern 'someInterestingString' ` 
    | Get-Member 

È inoltre possibile utilizzare l'alias gm invece.

+0

Questo è esattamente il tipo di risposta dettagliata che stavo cercando. Grazie! –

13

Quando sto facendo questo mi basta usare il parametro -List - sì lo fa visualizzare la riga di codice, ma si ottiene solo una riga per ogni file (indipendentemente dal numero di partite ci sono):

PS> Get-ChildItem . -r *.cs | Select-String XmlNode -list 

Commands\SnapinHelp\CmdletInfo.cs:27:  public List<XmlNode> InputTypes; 
Commands\SnapinHelp\GetSnapinHelpCommand.cs:124:   WriteXmlNodeList(c... 
Commands\SnapinHelp\ParameterInfo.cs:73:  XmlNode FindNode(XmlDocument doc) 
Commands\Xml\XmlCommandBase.cs:65:   RegisterInputType<XmlNode>(Proce... 

Se si desidera che il percorso:

PS> Get-ChildItem . -r *.cs | Select-String XmlNode -list | 
    Format-Table Path 

Path 
-------- 
C:\Users\Keith\Pscx\Src\PscxSnapin\Commands\SnapinHelp\CmdletInfo.cs 
C:\Users\Keith\Pscx\Src\PscxSnapin\Commands\SnapinHelp\GetSnapinHelpCommand.cs 
C:\Users\Keith\Pscx\Src\PscxSnapin\Commands\SnapinHelp\ParameterInfo.cs 
C:\Users\Keith\Pscx\Src\PscxSnapin\Commands\Xml\XmlCommandBase.cs 

Oppure, se si vuole veramente solo il nome del file:

PS> Get-ChildItem . -r *.cs | Select-String XmlNode -list | 
    Format-Table Filename 

Filename 
-------- 
CmdletInfo.cs 
GetSnapinHelpCommand.cs 
ParameterInfo.cs 
XmlCommandBase.cs 
+2

Molto più semplice della soluzione (più generica) sopra ... +1. –

+1

Solo il lato negativo di questo approccio è che se i file binari si trovano nel percorso di ricerca, la prima riga potrebbe essere l'intero file. – Tolga

+0

@Tolga Per rimuovere i binari, basta usare '-exclude * .dll, * .pdb, * .cache, * .exe' in ** get-childitem **, o qualsiasi altra estensione binaria che appare. – SliverNinja

1

I trovato più facile da fare

(...|select-string "search").Path 
+0

Funziona, ma restituirà il percorso del file ogni volta che viene cercata la stringa nel file. – Rod

Problemi correlati