Список имен файлов в папке, соответствующей шаблону, за исключением содержимого файла
Я использую ниже, чтобы рекурсивно перечислить все файлы в папке, содержащей $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