PowerShell эквивалентен grep -f

157

Я ищу PowerShell эквивалент grep --file=filename. Если вы не знаете grep, filename - это текстовый файл, в котором каждая строка имеет шаблон регулярного выражения, который вы хотите сопоставить.

Может быть, я упускаю что-то очевидное, но Select-String, похоже, нет этой опции.

Fordio
источник

Ответы:

178

-PatternПараметр Select-Stringподдерживает массив шаблонов. Итак, что вы ищете:

Get-Content .\doc.txt | Select-String -Pattern (Get-Content .\regex.txt)

При этом выполняется поиск по текстовому файлу doc.txtс использованием каждого регулярного выражения (по одному в строке) вregex.txt

Фроде Ф.
источник
6
Кроме того, завершение вкладки PowerShell сделает команды прописными, поэтому их нетрудно вводить.
Joon
3
@joon Несколько лет спустя, но я бы добавил, что Powershell не учитывает регистр, поэтому использование заглавных букв не является проблемой.
Ди-см
1
@ Vache конечно - я думаю, что мой комментарий выше является ответом на другой комментарий, но кажется, что комментарий больше не существует.
юн
85
PS) new-alias grep findstr
PS) C:\WINDOWS> ls | grep -I -N exe

105:-a---        2006-11-02     13:34      49680 twunk_16.exe
106:-a---        2006-11-02     13:34      31232 twunk_32.exe
109:-a---        2006-09-18     23:43     256192 winhelp.exe
110:-a---        2006-11-02     10:45       9216 winhlp32.exe

PS) grep /?
dawciobiel
источник
17
Я никогда не понимал, как это получило так много голосов. Это даже не отвечает на вопрос ..
Фроде Ф.
18
Что мне нравится в этом ответе, так это то, что он findstrработает так же, как grepв Linux. Select-Stringотлично подходит для работы с объектами, но иногда вы просто хотите сопоставить строки.
Элайджа В. Ганье
7
Стоит отметить, что findstrэто не родной для PowerShell, а командной строки.
анишпатель
1
Эта команда findstr уже была доступна для меня, и она работала так же, как unix GREP.
Леннон
37

Я не знаком с grep, но с Select-String вы можете сделать:

Get-ChildItem filename.txt | Select-String -Pattern <regexPattern>

Вы также можете сделать это с Get-Content:

(Get-Content filename.txt) -match 'pattern'
Шей Леви
источник
4
Расширен это, например dir *.cs -Recurse | sls "TODO" | select -Unique "Path". Спасибо за отличный указатель.
Йерун
4

Поэтому я нашел довольно хороший ответ по этой ссылке: https://www.thomasmaurer.ch/2011/03/powershell-search-for-string-or-grep-for-powershell/

Но по сути это так:

Select-String -Path "C:\file\Path\*.txt" -Pattern "^Enter REGEX Here$"

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

doc.txt:31: Enter REGEX Here
HelloWorld.txt:13: Enter REGEX Here
cody.tv.weber
источник
1
Он хочет загрузить шаблон из файла.
Брайан Гордон
2

На этот вопрос уже есть ответ, но я просто хочу добавить, что в Windows есть подсистема Windows для Linux WSL .

Так, например, если вы хотите проверить, есть ли у вас служба с именем Elasicsearch, которая находится в состоянии выполнения, вы можете сделать что-то похожее на фрагмент ниже в powershell

net start | grep Elasticsearch

Иван Руски
источник
2

У меня была такая же проблема при попытке найти текст в файлах с PowerShell. Я использовал следующее - чтобы оставаться как можно ближе к среде Linux.

Надеюсь, это кому-нибудь поможет:

PowerShell:

PS) new-alias grep findstr
PS) ls -r *.txt | cat | grep "some random string"

Объяснение:

ls       - lists all files
-r       - recursively (in all files and folders and subfolders)
*.txt    - only .txt files
|        - pipe the (ls) results to next command (cat)
cat      - show contents of files comming from (ls)
|        - pipe the (cat) results to next command (grep)
grep     - search contents from (cat) for "some random string" (alias to findstr)

Да, это работает также:

PS) ls -r *.txt | cat | findstr "some random string"
Магнус Эстерхуизен
источник
0

но у select-String, похоже, нет этой опции.

Верный. PowerShell не является клоном набора инструментов * nix shell.

Однако не сложно построить что-то подобное самостоятельно:

$regexes = Get-Content RegexFile.txt | 
           Foreach-Object { new-object System.Text.RegularExpressions.Regex $_ }

$fileList | Get-Content | Where-Object {
  foreach ($r in $regexes) {
    if ($r.IsMatch($_)) {
      $true
      break
    }
  }
  $false
}
Ричард
источник
Это плохой ответ. Select-String -Pattern somestringнамного чище
каньон Колоб
0

Может быть?

[regex]$regex = (get-content <regex file> |
foreach {
          '(?:{0})' -f $_
        }) -join '|'

Get-Content <filespec> -ReadCount 10000 |
 foreach {
           if ($_ -match $regex)
             {
              $true
              break
             }
         }
mjolinor
источник