PowerShell tương đương với grep -f


157

Tôi đang tìm PowerShell tương đương grep --file=filename. Nếu bạn không biết grep, tên tệp là một tệp văn bản trong đó mỗi dòng có mẫu biểu thức chính quy bạn muốn khớp.

Có lẽ tôi đang thiếu một cái gì đó rõ ràng, nhưng Select-Stringdường như không có tùy chọn này.

Câu trả lời:


178

Các -Patterntham số trong Select-Stringhỗ trợ một loạt các mô hình. Vì vậy, cái bạn đang tìm kiếm là:

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

Điều này tìm kiếm thông qua tệp văn bản doc.txtbằng cách sử dụng mọi regex (một trên mỗi dòng) trongregex.txt


6
Ngoài ra, việc hoàn thành tab PowerShell sẽ khiến các lệnh được viết hoa đúng cách, do đó không khó để nhập.
joon

3
@joon Một vài năm muộn, nhưng tôi nói thêm rằng Powershell không phân biệt chữ hoa chữ thường nên việc viết hoa các lệnh không phải là vấn đề.
dee-xem

1
@Vache tất nhiên - Tôi nghĩ bình luận của tôi ở trên là một phản hồi cho một bình luận khác, nhưng có vẻ như bình luận đã biến mất nữa.
joon

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 /?

17
Tôi không bao giờ hiểu làm thế nào điều này nhận được nhiều phiếu bầu. Nó thậm chí không trả lời câu hỏi ..
Frode F.

18
Điều tôi thích về câu trả lời này là findstrhoạt động giống như greptrên Linux. Select-Stringlà tuyệt vời để làm việc với các đối tượng, nhưng đôi khi bạn chỉ muốn khớp trên chuỗi.
Elijah W. Gagne

7
Điều đáng chú ý findstrlà không có nguồn gốc từ PowerShell, nhưng Command Prompt.
anishpatel

1
Lệnh findstr này đã có sẵn cho tôi và nó hoạt động giống như unix GREP.
Lennon

37

Tôi không quen với grep nhưng với Chuỗi chọn bạn có thể làm:

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

Bạn cũng có thể làm điều đó với Get-Content:

(Get-Content filename.txt) -match 'pattern'

4
Mở rộng này để ví dụ dir *.cs -Recurse | sls "TODO" | select -Unique "Path". Thx cho con trỏ tuyệt vời.
Jeroen

4

Vì vậy, tôi đã tìm thấy một câu trả lời khá hay tại liên kết này: https://www.thomasmaurer.ch/2011/03/powershell-search-for-opes-or-grep-for-powershell/

Nhưng thực chất nó là:

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

Điều này cho phép tìm kiếm tệp thư mục (* hoặc bạn chỉ có thể chỉ định một tệp) và tìm kiếm nội dung tệp tất cả trong một dòng của PowerShell, rất giống với grep. Đầu ra sẽ tương tự như:

doc.txt:31: Enter REGEX Here
HelloWorld.txt:13: Enter REGEX Here

1
Anh ta muốn tải mẫu từ một tập tin.
Brian Gordon

2

Câu hỏi này đã có câu trả lời, nhưng tôi chỉ muốn thêm rằng trong Windows có Windows subsystem cho Linux WSL .

Vì vậy, ví dụ nếu bạn muốn kiểm tra xem bạn có dịch vụ có tên Elasicsearch đang trong trạng thái đang chạy hay không, bạn có thể làm một cái gì đó giống như đoạn trích dưới đây trong powershell

net start | grep Elasticsearch


2

Tôi gặp vấn đề tương tự khi cố gắng tìm văn bản trong các tệp có powershell. Tôi đã sử dụng như sau - để càng gần môi trường Linux càng tốt.

Hy vọng rằng điều này sẽ giúp ai đó:

PowerShell:

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

Giải trình:

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)

Vâng, điều này cũng hoạt động:

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

0

nhưng select-String dường như không có tùy chọn này.

Chính xác. PowerShell không phải là một bản sao của bộ công cụ * nix shells.

Tuy nhiên, không khó để tự xây dựng một cái gì đó giống như nó:

$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
}

Đây là một câu trả lời xấu. Select-String -Pattern somestringsạch hơn nhiều
Kolob Canyon

0

Có lẽ?

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

Get-Content <filespec> -ReadCount 10000 |
 foreach {
           if ($_ -match $regex)
             {
              $true
              break
             }
         }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.