Удалите символ (@) и фигурную скобку ({) из вывода Select-Sring в Powershell - PullRequest
1 голос
/ 30 января 2020

Я анализирую имена файлов в Powershell, и когда я использую Get-ChildItem | select name, я получаю чистый вывод файлов:

file1.txt file2.txt file3.txt

Но когда я пытаюсь сузить те файлы с Select-String, я получаю странные @ и { перед моим выводом:

Get-ChildItem | select name | Select-String -Pattern "1"

@{file1.txt}

Есть ли параметр, который я пропускаю? Если я использую findstr вместо Select-String, это работает как заклинание:

Get-ChildItem | select name | Findstr "1"

file1.txt

1 Ответ

1 голос
/ 30 января 2020

Вы можете упростить и ускорить вашу команду следующим образом:

@((Get-ChildItem).Name) -match '1'

Примечание: @(), оператор массива-подвыражения , необходимо для обеспечения работы -match в массиве , даже если в текущем каталоге существует только один файл.

  • (...).Name использует перечисление члена для извлечения всех Name значений свойств из объектов file-info, возвращаемых Get-ChildItem.

  • -match оператор сопоставления регулярных выражений из-за работы с массивом значений возвращает вложенный массив совпадающих значений.


К заставить вашу оригинальную команду работать :

Get-ChildItem | select -ExpandProperty Name | 
  Select-String -Pattern "1" | select -ExpandProperty Line
  • select -ExpandProperty Name делает select (Select-Object) возврат только Name свойство значения ; по умолчанию (подразумевается -Property параметр) возвращается пользовательский объект , который имеет свойство Name .

  • select -ExpandProperty line аналогичным образом извлекается значение свойства Line из Microsoft.PowerShell.Commands.MatchInfo экземпляров, которые Select-String выводит.

    • Обратите внимание, что в PowerShell [Core] v7 + вы можно пропустить этот шаг, вместо этого используя Select-String (новый) -Raw переключатель для запроса вывода только для строки.

Что касается что вы пытались :

Как уже говорилось, не используя -ExpandProperty, select name (подразумеваемый параметр -Property) создал пользовательский объект ([pscustomobject] instance) с Name свойство.

Select-String переводит свои входные объекты в случае необходимости, поэтому он может выполнять поиск по ним по строкам, что приводит к отображению, которое вы видели; вот симуляция:

# Stringify a custom object via an expandable string ("...")
PS> "$([pscustomobject] @{ Name = 'file1.txt' })"
@{Name=file1.txt}

В качестве отступления:

  • Вышеуказанный метод строкового преобразования по сути похож на вызов .ToString() для входных объектов [1], что часто приводит к бесполезным строковым представлениям (по умолчанию только имя type ); более полезной и интуитивно понятной строковой системой будет использование расширенной системы форматирования вывода PowerShell, т.е. использование строкового представления, которое вы увидите в консоли ; изменение поведения Select-String для этого является предметом запроса этой функции на GitHub .

[1] Вызов .ToString() непосредственно на [pscustomobject] экземпляр на самом деле все еще не работает в PowerShell Core 7.0.0-r c .2 из-за этой ошибки ; Обходной путь должен вызвать .psobject.ToString() или использовать расширяемую строку, как показано выше.

...