2009-09-30 9 views
15

J'utilise powershell pour "grep" mon code source pour une chaîne particulière. Si la chaîne est dans le fichier, je voudrais le nom du fichier, pas la ligne de code qui contient la chaîne.nom de fichier de sortie, pas de chaîne avec select-string

Je voudrais également le nom du fichier, une seule fois, pas répertorié autant de fois que le fichier existe.

J'utilise actuellement:

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

Maintenant, je comprends que la sortie de select-string est une sorte de ojbect, et ce que je vois dans la console est, je suppose, la ToString() de cet objet. Je suppose que je pourrais utiliser format-table pour contrôler la sortie de la chaîne de sélection, et je suppose sort pour obtenir des valeurs distinctes seulement.

mais c'est beaucoup de deviner.

Répondre

32

Je ne pense pas que je comprends complètement ce que vous essayez de faire. Si vous voulez que la sortie groupée par fichier, vous pouvez tuyau dans Format-Table avec le paramètre -GroupBy:

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

Si vous souhaitez obtenir uniquement les noms des fichiers qui correspondent sans aucune autre information, vous pouvez utiliser Select-Object avec le paramètre -Unique:

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

Si vous êtes intéressé par seul le nom du fichier, quel que soit le nom lui-même apparaît plusieurs fois dans votre hiérarchie, vous pouvez sélectionner le lieu Filename propriété.


Note: L'applet de commande Get-Member est une grande aide pour déterminer quelles propriétés existent sur un objet:

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

Vous pouvez également utiliser son alias gm à la place.

+0

C'est exactement le genre de réponse détaillée que je cherchais. Merci! –

13

Quand je fais ce que je viens d'utiliser le paramètre -Liste - oui, il n'affiche la ligne de code, mais vous obtenez seulement une ligne par fichier (peu importe combien de matchs il y a):

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... 

Si vous voulez que le chemin:

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 

Ou si vous voulez vraiment que le nom du fichier:

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

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

Beaucoup plus simple que la solution (plus générique) ci-dessus ... +1. –

+1

Seul inconvénient de cette approche est que si les fichiers binaires sont dans le chemin de recherche, la première ligne peut-être le fichier entier. – Tolga

+0

@Tolga Pour supprimer les binaires, utilisez simplement '-exclude * .dll, * .pdb, * .cache, * .exe' dans ** get-childitem **, ou toute autre extension binaire qui apparaît. – SliverNinja

1

I trouvé plus facile à faire

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

Cela fonctionne, mais il retournera le chemin du fichier chaque fois que la chaîne recherchée est trouvée dans le fichier. – Rod