2009-03-05 43 views
18

Tôi có một tệp văn bản chứa các dòng dữ liệu. Tôi có thể sử dụng các kịch bản PowerShell sau để trích xuất các dòng Tôi quan tâm đến:Làm thế nào để bạn trích xuất giá trị của một regre backreference/match trong Powershell

select-string -path *.txt -pattern "subject=([A-Z\.]+)," 

Một số dữ liệu ví dụ sẽ là:

blah blah subject=THIS.IS.TEST.DATA, blah blah blah 

Những gì tôi muốn là để có thể để chỉ trích các nội dung thực tế của chủ đề (ví dụ: chuỗi "THIS.IS.TEST.DATA"). Tôi đã thử điều này:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0] } 

Nhưng thuộc tính "Kết quả phù hợp" luôn là rỗng. Tôi đang làm gì sai?

Trả lời

9

Tôi không biết tại sao phiên bản của bạn không hoạt động. Nó sẽ hoạt động. Đây là một phiên bản xấu hơn hoạt động.

$p = "subject=([A-Z\.]+)," 
select-string -path *.txt -pattern $p | % {$_ -match $p > $null; $matches[1]} 

Chỉnh sửa. Giải thích cho dant:

-match là một thường xuyên khai thác phù hợp với biểu hiện:

>"foobar" -match "oo.ar" 
True 

Các > $null chỉ ngăn chặn True được ghi vào đầu ra. (Hãy thử loại bỏ nó.) Có một lệnh ghép ngắn thực hiện cùng một điều mà tên tôi không nhớ lúc này.

$matches là biến số ma thuật giữ kết quả của hoạt động -match cuối cùng.

+0

Cảm ơn, điều đó có hiệu quả, nhưng bạn có thể giải thích những gì bạn đang làm không? Đặc biệt là bit "$ _ -match $ p> $ null". – d4nt

+1

Lệnh ghép ngắn có nghĩa là "Out-Null". Nhưng bạn cũng có thể truyền toàn bộ dòng tới [void]: [void] ($ _ -match $ p) – JasonMArcher

2

Sự cố với mã bạn đang nhập là chuỗi chọn không chuyển xuống đối tượng Regex thực tế. Thay vào đó nó vượt qua một lớp khác gọi là MatchInfo mà không có thông tin regex thực sự khớp với thông tin.

Nếu bạn chỉ muốn chạy regex một lần, bạn sẽ phải cuộn chức năng của chính bạn mà không quá khó.

function Select-Match() { 
    param ($pattern = $(throw "Need a pattern"), 
     $filePath = $(throw "Need a file path")) 
    foreach ($cur in (gc $filePath)) { 
    if ($cur -match $pattern) { 
     write-output $matches[0]; 
    } 
    } 
} 

gci *.txt | %{ Select-Match "subject=([A-Z\.]+)," $_.FullName } 
+0

Nhưng tại sao thuộc tính MatchInfo.Matches không hoạt động? http://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.matchinfo.matches(VS.85).aspx –

+0

@dangph, tôi tin rằng đó là lỗi trong tài liệu. Bạn có thể xác minh điều này bằng cách chạy "gci a * .txt | gm". Loại kết quả không có thuộc tính Kết quả phù hợp. – JaredPar

+0

JaredPar, điều đó không hiệu quả đối với tôi, nhưng tôi tin rằng bạn đúng. Hãy thử điều này: "gm -inputobject (đối tượng mới Microsoft.PowerShell.Commands.MatchInfo)". –

2

Tuy nhiên, một tùy chọn

gci *.txt | foreach { [regex]::match($_,'(?<=subject=)([^,]+)').value } 
2

Sau khi học được rất nhiều từ tất cả các câu trả lời khác tôi đã có thể có được những gì tôi muốn sử dụng các dòng sau:

gci *.txt | gc | %{ [regex]::matches($_, "subject=([A-Z\.]+),") } | %{ $_.Groups[1].Value } 

này cảm thấy thoải mái như Tôi đã chỉ chạy regex một lần trên mỗi dòng và khi tôi đã nhập vào lệnh này tại dấu nhắc lệnh nó là tốt đẹp không có nhiều dòng mã.

+0

Rất vui khi bạn tìm được giải pháp. Tôi vừa kiểm tra v2 và thuộc tính Matches hoạt động từ Select-String. Vì vậy, trong tương lai điều này sẽ ít đau đớn hơn cho bạn. :) – JasonMArcher

0

biến khác, phù hợp với 7 chữ số trong một chuỗi

echo "123456789 hello test" | % {$_ -match "\d{7}" > $null; $matches[0]} 

lợi nhuận: 1234567

4

Trong PowerShell V2 CTP3, Matches tài sản được thực hiện.Vì vậy, sau đây sẽ làm việc:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0].Groups[1].Value } 
1

Select-String lệnh dường như trở về một MatchInfo biến và không phải là một "chuỗi" biến. Tôi đã dành vài giờ để tìm hiểu điều này trên các diễn đàn và trang web chính thức không có may mắn. Tôi vẫn đang thu thập thông tin. Một khoảng cách này là tuyên bố rõ ràng một biến chuỗi để giữ kết quả trả về từ Select-String, từ ví dụ của bạn:

[chuỗi] $ foo = chọn dây -path * .txt -pattern " subject = ([AZ.] +), "

Biến $ foo giờ đây là một chuỗi chứ không phải đối tượng MatchInfo.

Hy vọng điều này sẽ hữu ích.

Phiên bản PowerSh5 PowerShell 5 Thao tác chuỗi chuỗi

Các vấn đề liên quan