web-dev-qa-db-fra.com

Répertorie les noms de fichier dans un dossier correspondant à un modèle, à l'exclusion du contenu du fichier

J'utilise ce qui suit pour répertorier de manière récursive tous les fichiers d'un dossier contenant le fichier $pattern

Get-ChildItem $targetDir -recurse | Select-String -pattern "$pattern" | group path | select name

Mais il semble que les deux fichiers de liste ayant le $pattern _ en son nom et en conten, par ex. quand je lance ce qui précède où $pattern="SAMPLE" Je reçois:

C:\tmp\config.include
C:\tmp\README.md
C:\tmp\specs\SAMPLE.data.nuspec
C:\tmp\specs\SAMPLE.Connection.nuspec

À présent:

C:\tmp\config.include
C:\tmp\README.md

contient en effet les mots-clés/texte SAMPLE, mais cela ne m’intéresse pas; j’ai seulement besoin de la commande pour répertorier les noms de fichiers et non les fichiers dont le contenu correspond au modèle. Qu'est-ce que je rate?

Sur la base des réponses ci-dessous, j'ai également essayé:

$targetDir="C:\tmp\"
Get-ChildItem $targetDir -recurse | where {$_.name -like "SAMPLE"} | group path | select name

et:

$targetDir="C:\tmp\"
Get-ChildItem $targetDir -recurse | where {$_.name -like "SAMPLE"} | select name

mais cela ne donne aucun résultat.

18
u123

Select-String fait ce que vous lui avez dit. L'accent est à moi.

La cmdlet Select-String recherche du texte et des modèles de texte dans les chaînes d'entrée et les fichiers .

Donc, si vous cherchez seulement à faire correspondre les noms de fichiers, utilisez simplement -Filter de Get-ChildItem ou post-traitement avec Where-Object

Get-ChildItem -Path $path -Recurse -Filter "*sample*"

Cela devrait renvoyer tous les fichiers et les dossiers qui ont un exemple dans leur nom. Si vous ne vouliez que des fichiers ou des répertoires, vous pourrez utiliser les commutateurs -File ou -Directory pour renvoyer ces types d'objet spécifiques.

Si votre modèle est plus compliqué qu'un simple mot, vous devrez peut-être utiliser Where-Object comme dans réponse d'Itchydon avec quelque chose comme -match vous donnant accès à regex.


La logique de regroupement dans votre code doit être redondante, car vous renvoyez des fichiers uniques qui ont tous des chemins uniques. Par conséquent, je n'ai pas inclus cela ici. Si vous voulez juste les chemins, vous pouvez diriger dans Select-Object -Expand FullName ou juste (Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname

30
Matt

To complémentréponse utile de Matt :

Plus précisément, parce que ce que vous dirigez vers Select-String sont [System.IO.FileInfo] objets - qui est ce que Get-ChildItem sorties - plutôt que chaînes, il s’agit du contents des fichiers représentés par ces objets est en cours de recherche .

En supposant que vous devez uniquement faire correspondre le nom du fichier au chemin de chaque fichier et que votre modèle puisse être exprimé sous la forme expression générique, vous n'avez pas besoin de Select-String du tout et peut à la place utiliser Get-ChildItem avec -Filter, comme dans la réponse de Matt, ou le plus lent, mais légèrement plus puissant -Include.

Avertissement:

  • Select-String -Pattern accepte un expression régulière (par exemple, .*sample.*; voir Get-Help about_Regular_Expressions),

  • tandis que Get-ChildItem -Filter/-Include accepte une expression expression générique (par exemple, *sample*; voir Get-Help about_Wildcards) - ils sont des choses différentes.

Sur une note de côté: Si votre intention est de faire correspondre à fichiers seulement, vous pouvez dire Get-ChildItem restreindre la sortie aux fichiers (par opposition à potentiellement aussi répertoires) en utilisant -File (de manière analogue, vous pouvez limiter la sortie aux répertoires avec -Directory).


Group-Object path (group path) ne fonctionnera pas comme prévu, car le .Path propriété des objets d’information de correspondance générés par Select-String contient le nom du fichier complet, de sorte que vous placeriez chaque fichier dans son propre groupe - essentiellement, un no-op.

Lorsque vous utilisez seulement Get-ChildItem, le nom de propriété équivalent serait .FullName, mais vous cherchez à grouper par parent chemin (le chemin du répertoire contenant), .DirectoryName), Je présume donc:

... | Group-Object DirectoryName | Select-Object Name

Ceci sort le chemin complet de chaque répertoire qui contient au moins 1 fichier avec un nom de fichier correspondant.
(Notez que le Name dans Select-Object Name se réfère à la .Name propriété des objets group renvoyés par Group-Object, qui dans ce cas est la valeur du .DirectoryName propriété sur les objets en entrée.)

7
mklement0
get-ChildItem $targetDir -recurse | where {$_.name -like $pattern} | select name
4
Itchydon

J'ai parcouru la réponse de @Itchydon

mais ne pouvait pas suivre l'utilisation de '-like' $ pattern.

J'essayais de lister les fichiers ayant 32 caractères (lettres et chiffres) dans le nom du fichier.

PS C:> Get-ChildItem C:\Users\ -Recurse | where {$_.name -match "[a-zA-Z0-9]{32}"} | select name

ou

PS C:> Get-ChildItem C:\Users\010M\Documents\WindowsPowerShell -Recurse | Where-Object {$_.name -match "[A-Z0-9]{32}"} | select name

Donc, dans ce cas, peu importe que vous utilisiez ou où-objet.

0
010 M

Vous pouvez utiliser select-string directement pour rechercher des fichiers correspondant à une certaine chaîne. Oui, cela renverra le nom de fichier: count: content ... etc. le "nom de fichier" pour faire ceci dirige ceci dans "select-object" en choisissant le "FileName" dans la sortie.

Ainsi, pour sélectionner tous les fichiers * .MSG dont le motif est "Objet: services Web redémarrés", vous pouvez procéder comme suit:

Select-String -Path. *. MSG -Pattern 'Subject: WebServices Restarted' - Liste | Nom de fichier select-object

En outre, pour supprimer ces fichiers à la volée, vous pouvez puiser dans une instruction ForEach avec la commande RM comme suit:

Select-String -Path. *. MSG -Pattern 'Subject: WebServices Restarted' - Liste | Nom du fichier select-object | foreach {rm $ _. FileName}

J'ai essayé moi-même, fonctionne à 100%.

J'espère que ça aide

0
Heider Sati