Как сделать многострочный Select-String?

Я пытаюсь Select-String в тексте, который состоит из нескольких строк.

Пример:

 "This is line1
 <Test>Testing Line 2</Test>
 <Test>Testing Line 3</Test>"

Я хочу иметь возможность выбрать все 3 строки в Select-String. Однако, когда я делаю Select-String -Pattern "Line1", я выбираю только первую строку. Как я могу извлечь все 3 строки вместе?

Select-String -Pattern "Line1"
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
11 218
2

Ответы 2

Select-String позволяет выбрать заданное количество строк до или после совпадающей строки с помощью параметра -Context. -Context 2,0 выбирает предыдущие 2 строки, -Context 0,2 выбирает последующие 2 строки, -Context 2,2 выбирает 2 строки до и 2 строки после совпадения.

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

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    $($_.Line; $_.Context.PostContext) | Out-String
}

Как правильно указал @mklement0 в комментариях, приведенное выше выполняется сравнительно медленно, что не является проблемой, если вы обрабатываете только несколько совпадений, но становится проблемой, если вам нужно обработать сотни или тысячи совпадений. Для повышения производительности вы можете объединить значения в один массив и использовать оператор -join:

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    (,$_.Line + $_.Context.PostContext) -join [Environment]::NewLine
}

Обратите внимание, что два фрагмента кода не дают точно такой же результат, потому что Out-String добавляет новую строку к каждой строке, включая последнюю, тогда как -join помещает новые строки только между строк (не в конец последней). Однако каждый фрагмент можно изменить, чтобы получить тот же результат, что и другой. Обрежьте строки из первого примера, чтобы удалить завершающие символы новой строки, или добавьте еще одну новую строку к строкам из второго примера.

Если вы хотите вывести отдельные строки, просто выведите свойства Line и PostContext, не объединяя их в одну строку:

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    $_.Line
    $_.Context.PostContext
}

Select-String работает со своими входными объектами индивидуально, и если вы либо передаете ему путь к файлу напрямую (через -Path или -LiteralPath), либо передаете вывод из Get-Content, сопоставление выполняется для каждого линия.

Таким образом, передать ваш ввод как одну многострочную строку, который, если он исходит из файла, проще всего достигается с помощью Get-Content -Raw (PSv3+):

Get-Content -Raw file.txt | Select-String -Pattern Line1

Обратите внимание, что это означает, что если соответствует шаблону, выводится файл весь контент доступен через свойство .Line выходного объекта.


Напротив, если вы хотите сохранить построчное сопоставление, но также зафиксировать фиксированное количество окружающие линии, используйте параметр -Context.

Get-Content file.txt | Select-String -Pattern Line1 -Context 0, 2

Полезный ответ Ансгара Вихерса показывает, как извлечь все строки из результата.

Select-String operates on its input objects individually это критическая точка!
metablaster 15.04.2021 12:52

Также странные вещи происходят в подсказке по сравнению со сценарием. В приглашении select-string ищет \r на концах строк необработанных строк в окнах, и возникает проблема вставки вкладок или вставки буквальных вкладок в приглашении.

js2010 02.09.2021 00:39

Другие вопросы по теме