Как в powershell найти строку
Перейти к содержимому

Как в powershell найти строку

  • автор:

GREP в PowerShell: Поиск текста в файле с Select-String

date

02.09.2021

user

itpro

directory

PowerShell, Windows 10, Windows Server 2019

comments

комментариев 17

В мире Linux/Unix для поиска определенного текста или ошибок в лог файлах используется команда grep. Grep позволяет быстро и удобно найти/выбрать любых данные из результатов выполнения другой команды:

command | grep search

В PowerShell для поиска текста в файлах можно использовать командлет Select-String.

Например, следующая команда выведет все строки текстового файла, содержащие ключевую фразу ERROR:

Select-String -Path c:\tmp\makeapp_sxtracesxs.txt -Pattern «ERROR»

select-string поиск строки в файле с помощью PowerShell

Команда вывела номера строк, в которых содержится искомый тескт и их содержимое.

Если вам нужно выполнить поиск вхождения строки по всем txt файлам в определенном каталоге, выполните команду:

Select-String -Path c:\tmp\*.txt -Pattern «ERROR»

Такую команду удоно исопльзовать, если нужно выполнить поиск по всем файлам в каталоге. Например, для поиска в транспортных логах/smtp Exchange.

С помощью опций Exclude/Include можно включить, исключить определенннные файлы для поиска. Следующий пример выполнит поиск по всем txt и log файлам, имя которых не содежит copy:
$path = «c:\tmp\*»
Select-String -Path $path -Pattern «ERROR» -Include «*.txt»,»*.log» -Exclude «*copy*»

Предудущий пример выполняет поиск текста только в указанном каталоге. Для рекурсивного поиска по файлам во вложенных каталогах используйте Get-ChildItem:

Get-ChildItem -Path ‘c:\tmp\’ -Recurse -include «*.mp3″,»*.avi» -ErrorAction SilentlyContinue | Select-String -SimpleMatch «ERROR»,»WARNING»

Предыдущая статьяПредыдущая статья Следующая статья Следующая статья

Читайте далее в разделе PowerShell Windows 10 Windows Server 2019

page

page

page

Настройка NIC Teaming в Windows Server 2019/2016 и Windows 10

Send-MailMessage: отправка писем из PowerShell

Как расширить диск виртуальной машины в VMware?

Сброс пароля компьютера в домене без перезагрузки

Как искать в Powershell используя Select-String

GREP в Powershell - поиск через Select-String

В Powershell есть командлет, похожий на grep в Linux, Select-String. С помощью него мы можем искать как файлы, так и вхождения строк и, по желанию, используя регулярные выражения.

Для поиска внутри файла можно выполнить следующий командлет:

Select-String -Path *.txt -Pattern "fix"
  • Path — путь до директории или документа. В моем случае будут искаться все файлы с расширением .txt, т.к. знак * говорит что мы не знаем что находится слева. Если путь не указан, то он используется по умолчанию, откуда запущен powershell.
  • Pattern — строка, которую мы ищем внутри файла. Этот ключ используется для регулярных выражений. Для использования простого поиска, без регулярки, нужно ставить -SimpleMatch

Powershell Grep поиск строки

Мы можем искать не только в файлах, но и в самих строках:

$str = "Hello World" Select-String -InputObject $str -SimpleMatch "hello","idk"
  • InputObject — объект, в котором мы будем искать переменную
  • SimpleMatch — простое совпадение. В моем случае их два. Если «hello» или «idk» будет в строке, то команда вернет строку.

Если мы используем путь в какую-то папку, то мы можем включать и исключать какие-то свойства:

$path = "C:\Folder1\New folder\*" Select-String -Path $path -SimpleMatch "fix" -Include "*.txt" -Exclude "text*" -CaseSensitive
  • $path — переменная с путем, которая включает все файлы в папке «New Folder».
  • Include — включает все файлы. В моем случае с расширением .txt
  • Exclude — исключает все файлы, которые начинаются на text.
  • CaseSensitive — учет регистра. В powershell, по умолчанию, буква «а» и «А» одинаковые, а с этим ключом они будут разными.

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

Get-ChildItem -Path 'C:\Folder1\' -Recurse -Exclude "*.mp3" | Select-String -SimpleMatch "fix"
  • Recurse — рекурсивный поиск т.е. поиск по всем папкам включительно.
  • Exclude — исключаем файлы с расширением mp3

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

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

Get-ChildItem -Path 'C:\Folder1\' -Recurse -Exclude "*.mp3" -ErrorAction SilentlyContinue | Select-String -SimpleMatch "fix" -NotMatch
  • NoMatch — говорит, что нам нужны только те строки, где нет «fix» или дословно «Не совпадает»
  • ErrorAction — со значением SilentlyContinue — говорит «не уведомлять об ошибках».

Разницу с Nomatch можно увидеть на картинке:

Powershell Grep поиск файлов

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

  • ASCII
  • BigEndianUnicode
  • OEM
  • Unicode
  • UTF7
  • UTF8
  • UTF8BOM
  • UTF8NoBOM
  • UTF32

Как найти строки в логах с помощью powershell?

Здравствуйте. Ищу помощи. Имеется большое количество логов *.html. Необходимо осуществить поиск тех логов, в которых 2 события произошли строго друг за другом:
«дата время»,38, ip адрес,»Подключение серверу. Установлено.»,»пользователь (comp )»
«дата время»,156,ip адрес,,»Доступ отключен.»,
Пример
.
«2022-04-03 09:00:00″,38,10.200.125.20,»Подключение серверу. Установлено.»,»пользователь 1 (comp 1)»
«2022-04-03 09:29:44″,156,10.200.125.20,»Доступ отключен.»,
.
параметры : дата время, ip адрес, пользователь комп — меняются, собственно поиск осуществляется по коду события, наименованию события.

  • Вопрос задан более года назад
  • 94 просмотра

Комментировать
Решения вопроса 1
Cloud infrastructure, monitoring engineer. SRE

$x=gc *.html for ($i=0; $i -le $x.Length; $i++) < if ((ConvertFrom-Csv -Delimiter "," -Header "a","b","c","d","e","f" -inputobject $x[$i]).b -eq "38" -and (ConvertFrom-Csv -Delimiter "," -Header "a","b","c","d","e","f" -inputobject $x[$i+1]).b -eq "156" ) < echo $x[$i] $x[$i+1] >>

самое тупое что в голову пришло. оно будет тормозить ибо создаст объект со ВСЕМИ строками из всех файлов и пройдется по ним последовательно
а да, возможно надо будет делать парсинг html вытаскивая оттуда только текстовый контент

Ответ написан более года назад
Нравится 2 4 комментария
fjord_sy @fjord_sy Автор вопроса

спасибо за решение, скрипт отрабатывает с ошибкой, результат таков:
«2022-04-03 09:00:00″,38,10.200.125.20,»Подключение серверу. Установлено.»,»пользователь 1 (comp 1)»
«2022-04-03 09:29:44″,156,10.200.125.20,»Доступ отключен.»,
«2022-02-03 10:00:00″,38,10.200.125.20,»Подключение серверу. Установлено.»,»пользователь 1 (comp 1)»
«2022-02-03 10:29:44″,156,10.200.125.20,»Доступ отключен.»,
ConvertFrom-Csv : Не удается проверить аргумент для параметра «InputObject». Аргумент имеет значение NULL. Укажите допустимое значение аргумента, после чего повторите выполнение команды.
строка:4 знак:86
+ . miter «,» -Header «a»,»b»,»c»,»d»,»e»,»f» -inputobject $x[$i]).b -eq .
+ ~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Csv], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ConvertFromCsvCommand

fjord_sy, ну дебажьте convertfrom-csv коммандлет
так-то можно было и без импорта CSV строки, делать проверки с парсингом через
regexp
split
или Select-String, switch

Мне показалось что у вас единый формат записей, поэтому CSV и использовал
P.S. я не знаю какая версия PoSh у вас, поэтому какие-то из предложенных вариантов могут не работать в вашей версии, читайте документацию

Powershell. Поиск в тексте

Использовать командлет Select-String можно разными способами. Например подавать содержимое файлов через конвейер:

Get-Content $Files | Select-String «sendreports» | ?

Но лучше указывать объект с данными в виде аргумента InputObject, так как это выполняется гораздо быстрее:

Select-String -InputObject $(Get-Content $Files) -Pattern «sendreports» | ?

В поисках производительности

Если замерить скорость выполнения этой команды, то она будет крайне не высокой:

Measure-Command < Get-Content $Files | Select-String "sendreports" | ? < $_ -match "2018-11-16" >> # 260 Seconds

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

# Measure-Command показывает что такая команда выполняется в 20 раз быстрее предыдущей Measure-Command < Select-String -Path $Files -Pattern "sendreports" | ? < $_ -match "2018-11-16" >> # 12 Seconds
Workflow

Так же попробовал несколько вариантов использования Select-String в Workflow.
Сначала вариант с циклом:

Так как командлет Where-Object не поддерживается в Workflow,
то фильтры можно вынести либо за его пределы,
или же поместить в InlineScript

$Files = ( dir "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\FrontEnd" -Recurse -Filter "*.log" ).FullName workflow FindString($Files) < foreach -parallel ($file in $workflow:files)< (Select-String -Path $file -Pattern "sendreports" ).line | Write-Output >> Measure-Command < FindString $Files | ? < $_ -match "2018-11-16" >> # 18 Seconds

На удивление, никакого прироста скорости поиска я не получил, даже увеличивая значение «-throttlelimit»

Самым быстрый вариант

Здесь в блоке parallel мы, используя InlineScript, заносим результат Select-String в массив

workflow FindString< $Files = ( dir "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\FrontEnd" -Recurse -Filter "*.log" ).FullName $yourData = @() parallel < $workflow:yourData += inlinescript< Select-String -Path $using:Files -Pattern "sendreports" | ? < $_ -match "2018-11-16" >>> $yourData.line >; Measure-Command < FindString ># 7 Seconds

Не могу объяснить за счет чего именно достигается увеличение скорости поиска, тем не менее, при необходимости найти документ или строки в большом объеме данных, можно использовать эту конструкцию.
Можно искать по всем дискам компьютера, или же и вовсе по списку компьютеров.
Думаю в этом случае мы получим прирост по времени, значительно больший чем 3 секунды

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *