2016-11-27 2 views
1

Я использую команду PowerShell, чтобы найти все * .vue файлов (это простой текстовый формат) в директории, где мне нужно, чтобы соответствовать этому:матча многострочных строки

7,Id 
6,Default

Итак, это 2 последовательных линии. В Notepad ++ я вижу CRLF в конце строки. После поисков Google это должно быть близко:

Get-ChildItem "D:\Wim\TM1\TI processes" -Filter *.vue -Recurse | 
    Select-String -Pattern "7,Id\r\n6,Default" -CaseSensitive | 
    Out-File C:\test.txt 

Но он не находит файлы. Я проверил, что я могу найти первую часть (7,Id) правильно, а также вторую часть (6,Default), но комбинация с новой линией не работает.

Любые идеи, пожалуйста? Может быть, альтернатива?

У меня может быть обходное решение, но оно неэффективно и много кодирования. Например, я могу использовать PowerShell, чтобы предоставить список только первого предложения, а затем обработать эти файлы, чтобы увидеть, соответствует ли оно второму предложению. Я хочу этого избежать.

ответ

1

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

Get-ChildItem "D:\Wim\TM1\TI processes" -Filter *.vue -Recurse | ForEach-Object { 
    Get-Content $_.FullName | Out-String | 
    Select-String -Pattern "7,Id\r\n6,Default" -CaseSensitive | 
    Select-Object -Expand Matches | 
    Select-Object -Expand Groups | 
    Select-Object -Expand Value 
} | Out-File C:\test.txt 

На PowerShell v3 и выше вы можете использовать Get-Content -Raw вместо Get-Content | Out-String.

В качестве альтернативы Select-String можно использовать оператор -cmatchWhere-Object в фильтре:

Get-ChildItem "D:\Wim\TM1\TI processes" -Filter *.vue -Recurse | ForEach-Object { 
    Get-Content $_.FullName | Out-String | Where-Object { 
    $_ -cmatch "7,Id\r\n6,Default" 
    } | ForEach-Object { 
    $matches[0] 
    } 
} | Out-File C:\test.txt 
+0

Здравствуйте, Weird! Я собирался опубликовать, что второе предложение Ansgar Wiechers работает, но только один раз! Не уверен, что я понимаю, что происходит, но я получил результат 2 строк в файле C: \ test.txt, и с тех пор я больше не могу воспроизвести успех. Нет C: \ test.txt. Первое предложение Ansgar Wiechers и предложение jj27 не возвратили файл «C: \ test.txt» с самого начала. Еще раз спасибо! –

+0

Проверьте трубопровод шаг за шагом. Включает ли 'Get-ChildItem' соответствующие файлы? Действительно ли они содержат строки, о которых идет речь? Соответствует ли 'Where-Object' что-то? Выводит ли 'ForEach-Object' соответствующие строки? Если вход не изменился, нет причин, по которым приведенные выше утверждения должны работать только один раз. –

+0

Извинения, это был способ копирования/вставки самостоятельно. Когда я скопировал ваши решения из SO, я вставил и >> появился перед строками. Я вошел и ничего не произошло. Затем я понял, что нужно создать 1 длинное предложение и нажать Enter. Бинго! Оба решения работают, спасибо вам большое!Только один вопрос о последующих действиях: можем ли мы также иметь полное имя (путь и имя файла) в выходном текстовом файле, а не две соответствующие строки? Тогда это прекрасно. –

0

С Select-String, параметром -Pattern является регулярным выражением способен, поэтому попробовать это:

Get-ChildItem "D:\Wim\TM1\TI processes" -Filter *.vue -Recurse | 
    Select-String -Pattern "7,Id|6,Default" -CaseSensitive | 
    Out-File C:\test.txt 

Бар вертикальной труба (|) действует в качестве альтернативного сепаратора, или в других случаях, оператору «или» оператором. С шаблоном он будет соответствовать.

+0

Используя чередование будет производить ложные срабатывания, например, когда строки появляются в неправильном порядке, или один из них отсутствует вообще. –

+0

Действительно, мне нужно совместить эти строки, но никакие другие строки не могут быть между ними, а также должен применяться правильный порядок. –