Список имен файлов в папке, соответствующей шаблону, за исключением содержимого файла

Я использую ниже, чтобы рекурсивно перечислить все файлы в папке, содержащей $pattern

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

Но он кажется, что оба файла списка имеют $pattern в его имени и в его содержимом, например. когда я запускаю выше, где $pattern="SAMPLE" я получаю:

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

Сейчас:

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

действительно содержит ключевые слова/текст SAMPLE, но мне все равно, мне нужна только команда, чтобы перечислять имена файлов, а не файлы с содержимым, соответствующим шаблону. Что мне не хватает?

На основании приведенных ниже ответов я также попытался:

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

и

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

но он не возвращает никаких результатов.

Ответ 1

Select-String делает то, что вы ему сказали. Акцент на мой.

Командлет Select-String ищет текстовые и текстовые шаблоны во входных строках и файлах.

Итак, если вы просто хотите совместить с именами файлов, просто используйте -Filter of Get-ChildItem или отправьте процесс с помощью Where-Object

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

Это должно возвращать все файлы и папки с образцом в их имени. Если вы просто хотели файлы или каталоги, вы могли бы использовать переключатели -File или -Directory для возврата этих типов конкретных объектов.

Если ваш шаблон более сложный, чем простое слово, вам может понадобиться использовать Where-Object, как в Ответ Itchydon, с чем-то вроде -match, дающим вам доступ к регулярное выражение.


Логика группировки в вашем коде должна быть избыточной, поскольку вы возвращаете одиночные файлы, все из которых имеют уникальные пути. Поэтому я не включил это здесь. Если вам просто нужны пути, вы можете перейти в Select-Object -Expand FullName или просто (Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname

Ответ 2

В дополнение к Мэтт полезный ответ:

В частности, поскольку то, что вы пишете на Select-String, [System.IO.FileInfo] objects - это то, что Get-ChildItem выводит - , а не строки, это содержимое файлов, представленных этими объектами, выполняется поиск.

Предполагая, что вам нужно сопоставить только часть имени файла для каждого пути к файлу и что ваш шаблон может быть выражен как выражение подстановки, вам вообще не нужно Select-String и вместо этого использовать Get-ChildItem с -Filter, как в ответе Мэтта, или медленнее, но немного более мощным -Include.

Предостережение:

  • Select-String -Pattern принимает регулярное выражение (например, .*sample.*, см. Get-Help about_Regular_Expressions),

  • тогда как Get-ChildItem -Filter/-Include принимает подстановочное выражение (например, *sample*, см. Get-Help about_Wildcards) - это разные вещи.

Обратите внимание: если ваше намерение состоит в том, чтобы сопоставлять только файлы, вы можете указать Get-ChildItem ограничить вывод файлов (в отличие от потенциально также каталогов) с помощью -File (аналогично, вы можете ограничить вывод в каталогах с помощью -Directory).


Group-Object path (group path) не будет работать так, как предполагалось, потому что свойство .Path объектов сопоставления информации, выводимых Select-String, содержит полное имя файла, поэтому вы должны помещать каждый файл в свой собственный группа - по существу, no-op.

При использовании только Get-ChildItem эквивалентное имя свойства будет .FullName, но то, что вы ищете, это группировать по родительскому пути (содержащему путь к каталогу), .DirectoryName), я полагаю, поэтому:

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

Это выводит полный путь к каждой директории, содержащей по крайней мере 1 файл с соответствующим именем файла.
(Обратите внимание, что Name в Select-Object Name относится к свойству .Name для объектов группы, возвращаемых Group-Object, что в этом случае является значением свойства .DirectoryName на входных объектах.)

Ответ 3

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

Ответ 4

Вы можете использовать select-string напрямую для поиска файлов, соответствующих определенной строке, да, это вернет имя файла: count: content... и т.д., Но внутренне они имеют имена, которые вы можете выбрать или опустить, то, что вам нужно, это "имя файла", чтобы сделать этот канал в "select-object", выбрав "FileName" из выходных данных.

Итак, чтобы выбрать все файлы *.MSG с шаблоном "Subject: Webservices restarted", вы можете сделать следующее:

Select-String -Path. *. MSG -Pattern 'Тема: перезапуск веб-сервисов' -List | Выбрать объект Имя файла

Кроме того, чтобы удалить эти файлы на лету, вы можете добавить в оператор ForEach команду RM следующим образом:

Select-String -Path. *. MSG -Pattern 'Тема: перезапуск веб-сервисов' -List | объект выбора имя файла | foreach {rm $ _. FileName}

Я сам попробовал, работает на все 100%.

надеюсь, это поможет

Ответ 5

Я прошел через ответ @Itchydon

но не может следовать использованию шаблона [-like '$.

Я пытался перечислить файлы, имеющие 32 символа (буквы и цифры) в имени файла.

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