Поиск по сайту:

Как использовать эквивалент Grep в PowerShell - Select-String


Когда вам нужно искать в строке или логах в Linux, мы можем использовать команду grep. Для PowerShell мы можем использовать эквивалент grep Select-String. С помощью этого мощного cmdlet мы можем получить практически те же результаты.

Select-String использует регулярные выражения, похожие на grep, для поиска текстовых шаблонов в файлах и строках. Он может искать по нескольким файлам и сообщать о местоположении, включая номер строки строки для каждого файла. Также возможно найти только первое вхождение строки или, например, вернуть только файлы, которые не соответствуют строке.

В этой статье мы посмотрим на эквивалент grep в PowerShell Select-String. Мы рассмотрим различные примеры, которые вы можете использовать для поиска строки с помощью PowerShell. Обязательно прочитайте статью до конца, чтобы получить приятный маленький совет!

Поиск строки с помощью PowerShell Select-String

Прежде чем погрузиться во все возможности командлета select-string, давайте сначала рассмотрим несколько общих примеров. Чтобы искать определенную строку в файлах журналов, мы можем использовать следующий командлет в PowerShell:

Search for the string error in the path
Select-String -Pattern "error" -Path "C:\temp\log\*.log"

or in short:
Select-String "error" "C:\temp\log\*.log"

Эквивалент grep будет:

grep "error" .\log\*.log

По умолчанию вывод команды select-string будет показывать имя файла, номер строки и полную строку, в которой была найдена строка:

Эквивалент Grep в Powershell

Преимущество PowerShell заключается в том, что мы можем легко форматировать вывод в более удобочитаемом формате. Если вам, например, интересны только имя файла, путь и номер строки, то вы можете отформатировать результаты в таблицу и выбрать только те поля, которые вам нужны:

Select-String -Pattern "error" -Path "C:\temp\log\*.log" | Select LineNumber, FileName, Path

Result:
LineNumber Filename         Path
---------- --------         ----
         9 01032022-app.log C:\temp\log\01032022-app.log
        18 04032022-app.log C:\temp\log\04032022-app.log
         7 05032022-app.log C:\temp\log\05032022-app.log
         9 11022022-app.log C:\temp\log\11022022-app.log
         9 11032021-app.log C:\temp\log\11032021-app.log
         9 11102021-app.log C:\temp\log\11102021-app.log
        38 11102021-app.log C:\temp\log\11102021-app.log
         9 15032022-app.log C:\temp\log\15032022-app.log

Параметры Select-String

Итак, мы быстро ознакомились с основным использованием cmdlet, теперь давайте углубимся в возможности cmdlet поиска строк в PowerShell. Cmdlet имеет несколько параметров, которые помогут нам искать строки и выбирать результаты:

-Pattern

Текст или строка для поиска. Принимает регулярное выражение.

-Path

Укажите файл или путь к файлам, в которых нужно выполнить поиск. Поддерживается использование подстановочных знаков.

-CaseSensitive

Поисковая строка чувствительна к регистру

-Context

Показать строки перед и/или после шаблона

-Quiet

Возвращайте только истинное или ложное

-Raw

Возвращайте только совпадающую строку, как grep

-List

Перечислите только первое совпадение в файлах. Используется для получения списка файлов с шаблоном

-SimpleMatch

Считайте шаблон простым строковым значением

-Include

Указывает файлы, которые следует включить в поиск ("*.txt", "*.log")

-Exclude

Указывает файлы, которые следует исключить из пути поиска

-NotMatch

Верните только элементы, которые не соответствовали шаблону

-AllMatches

Вернуть все совпадения результата

Параметры Select-String

Показана строка перед и после с контекстом

Командлет Select-String возвращает строку, в которой найдена искомая строка. Но при поиске в журнальных файлах, например, вы, вероятно, также хотите знать, что произошло до или после ошибки.

Здесь вступает в игру параметр -context. Он позволяет указать количество строк, которые нужно вернуть до и/или после совпавшей строки. Первая цифра — это количество строк перед, вторая — количество строк после. Если вы укажете только одну цифру, она будет использована для обеих сторон.

Return 3 lines before
Select-String -Pattern "error" -Path "C:\temp\log\sub\*.log" -Context 3,0

Return 2 lines before and 2 lines after the error:
Select-String -Pattern "error" -Path "C:\temp\log\sub\*.log" -Context 2

Строка, соответствующая шаблону, отмечена >, а строка выделена:

cmdlet Select-String PowerShell

Вернуть True или False с Quiet

При использовании эквивалента grep в PowerShell, select-string, внутри скрипта иногда нужно всего лишь узнать, существует ли строка или нет. По умолчанию, cmdlet вернет объект MatchInfo. Объект с номером строки, путём, строкой и т.д.

Чтобы проверить, содержат ли файлы журналов ошибку или нет, мы можем сделать следующее:

Returns true or False
Select-String -Pattern "error" -Path "C:\temp\log\sub\*.log" -Quiet

Result:
True

Вернуть только совпадающую строку с Raw

Если вы привыкли к команде grep в Linux, то, возможно, заметили, что результат select-string немного отличается. Эквивалент PowerShell возвращает объект, а не только строку, как это делает команда grep.

Когда вы добавляете параметр -raw к вашей команде, cmdlet будет возвращать только строку, которая совпадала с шаблоном:

Select-String -Pattern "error" -Path "C:\temp\log\sub\*.log" -Raw

Result:
2022-03-01 10:59:21 [ERROR] - String failed to be a string

Ищите по нескольким типам файлов

Параметр пути уже поддерживает подстановочные знаки, что позволяет нам искать в нескольких файлах. Но в этом случае мы можем искать только в одном типе файла. Используя параметр -include, мы можем указать несколько типов файлов, которые мы хотим просмотреть.

Чтобы использовать параметр, нам все равно нужно указать путь, в противном случае командлет будет искать в корневом местоположении скрипта.

Search in the txt and log files
Select-String -Pattern "error" -Path "C:\temp\log\sub\*" -Include "*.txt","*.log"

Result
C:\temp\log\sub\LT3452-process.log:4:2022-03-01 10:59:21 [ERROR] - String failed to be a string
C:\temp\log\sub\LT4423-process.txt:3:2022-02-01 05:49:21 [ERROR] - Squirrel failed to find process

Также возможно исключить расширения файлов с помощью параметра -exclude.

Перечислите только файлы с помощью Select-String

При поиске по нескольким файлам с помощью командлета select-string PowerShell вернет все экземпляры найденной строки. Но иногда вам нужно только знать, содержит ли, например, файл журнала ошибку.

Если мы поищем в логах по шаблону ошибки, мы можем увидеть, что файл 11102021-app.log найден дважды:

Select-String -Pattern "error" -Path "C:\temp\log\*" | Select LineNumber, Filename

Result:
LineNumber Filename
---------- --------
         9 01032022-app.log
        18 04032022-app.log
         7 05032022-app.log
         9 11022022-app.log
         9 11032021-app.log
         9 11102021-app.log
        38 11102021-app.log
         9 15032022-app.log

Используя параметр -List, возвращаются только первые экземпляры, что приводит к уникальному списку имен файлов, содержащих совпадающий шаблон:

Select-String -Pattern "error" -Path "C:\temp\log\*" -List | Select LineNumber, Filename

Уникальные файлы с параметром -list

Возврат строк без шаблона

Все это время мы искали строки в лог-файлах, которые содержат строку "ошибка". Но что, если вы хотите получить противоположное? Все строки, которые не содержат слово "ошибка"?

Для этого мы можем использовать параметр -NotMatch. Это вернет все строки в пути, которые не соответствуют шаблону, который мы предоставили:

Select-String -Pattern "error" -Path "C:\temp\log\*" -NotMatch | Select LineNumber, Filename

Найдите файлы, которые не соответствуют шаблону

Командлет Select-String выполняет поиск на уровне строк в файлах. Это означает, что мы не можем просто использовать этот командлет, чтобы вернуть только те файлы, которые не содержат определенную строку.

Чтобы получить все файлы, которые не содержат строку, нам нужно использовать командлет Get-ChildItem и применять командлет Select-String к каждому файлу.

Используя параметр -quiet, мы можем вернуть true или false, что позволяет нам выбирать (и возвращать) только файлы, которые не содержат шаблон:

Get-ChildItem -path "C:\temp\log\*" | Where-Object { !( $_ | Select-String -Pattern "error" -Quiet ) }

Result:

    Directory: C:\temp\log

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           15-3-2022    13:52                sub
-a---           15-3-2022    14:09           4120 04032022-app.log
-a---           15-3-2022    12:59           2860 11032022-app.log

PowerShell Select-String рекурсивно

Команда select-string в PowerShell ищет только в указанном каталоге. Она не пройдет через подпапки, даже если вы используете подстановочные знаки. Чтобы искать во всех подпапках, нам нужно будет объединить командлет с Get-ChildItem.

Итак, чтобы искать во всех подпапках, мы сначала получим все элементы с помощью Get-Childitem, используя параметр -Recurse, чтобы искать рекурсивно. А затем передадим каждый файл командлету Select-String:

Get-ChildItem -path "C:\temp\log\*" -Recurse | Select-String -Pattern "error" | Select LineNumber, Filename, Path

PowerShell Select-String рекурсивно

PowerShell Выбор-Строки Несколько Шаблонов

При поиске в лог-файлах или других текстовых файлах иногда необходимо искать несколько шаблонов. Теперь вы могли бы просто запустить команду Select-String дважды, но это не совсем эффективно.

К счастью, мы можем предоставить несколько шаблонов командлету Select-String. Вы можете просто создать массив со строками или разделить строки запятыми:

Select-String -Pattern "error","warning" -Path "C:\temp\log\*" -List | Select LineNumber, Filename, Pattern

Несколько шаблонов

Как вы можете видеть, я добавил свойство Pattern к оператору select. Таким образом, мы можем увидеть, какой шаблон соответствует файлу и на какой строке.

Завершение

Эквивалент grep в PowerShell, Select-String, является отличным инструментом для поиска строк внутри текстовых файлов или другихoutput streams. Если вам действительно нравится использовать команду grep, у меня есть небольшой совет для вас. Вы можете создать новый псевдоним в PowerShell, чтобы при вводе grep использовалась команда select-string.

Чтобы создать псевдоним, введите:

new-alias grep select-string

Теперь вы можете использовать grep так же, как в Linux:

Алиас Греп

Надеюсь, вы нашли эту статью полезной. Если у вас есть вопросы, просто оставьте комментарий ниже.