[英]PowerShell regex to extract SID from filename
我有一個數組$ vhdlist,其內容類似於以下文件名:
UVHD-S-1-5-21-8746256374-654813465-374012747-4533.vhdx
UVHD-S-1-5-21-8746256374-654813465-374012747-6175.vhdx
UVHD-S-1-5-21-8746256374-654813465-374012747-8147.vhdx
UVHD-template.vhdx
我想使用一個正則表達式,並保留一個僅包含文件名的SID部分的數組。
我正在使用以下內容:
$sids = foreach ($file in $vhdlist)
{
[regex]::split($file, '^UVHD-(?:([(\d)(\w)-]+)).vhdx$')
}
這有兩個問題:在結果數組中,每個SID都有3條空行; 並且“模板”文件名匹配(輸出中的結果行僅是“模板”)。 如何獲得SID數組作為輸出而不包含“ template”行?
您似乎想將列表篩選為包含SID的文件名。 過濾是通過Where-Object
(簡稱where
)完成的; 您不需要循環。
對於這種簡單情況,SID可以描述為“ S-
,然后是一堆數字和破折號” 。 這給我們留下了^UVHD-S-[\\d-]*\\.vhdx$
作為文件名。
結合起來,我們得到:
$vhdlist | where { $_ -Match "^UVHD-S-[\d-]*\.vhdx$" }
當您實際上沒有字符串數組,而是實際上有文件數組時,請直接使用它們。
dir C:\some\folder | where { $_.Name -Match "^UVHD-S-[\d-]*\.vhdx$" }
或者,甚至可以將其簡化為:
dir C:\some\folder\UVHD-S-*.vhdx
編輯
從字符串列表中提取SID可以看作是組合轉換 (對於每個元素,提取SID)和過濾 (刪除不匹配項)操作。
PowerShell的ForEach-Object
cmdlet(簡稱foreach
)的工作方式與其他語言中的map()
相似。 它接受每個輸入元素並返回一個新值。 實際上,它將輸入元素列表轉換為輸出元素。 與-replace
運算符一起,您可以通過這種方式提取SID。
$vhdlist | foreach { $_ -replace ^(?:UVHD-(S-[\d-]*)\.vhdx|.*)$,"`$1" } | where { $_ -gt "" }
.NET語言的正則表達式后向引用為$1
。 $
是PowerShell字符串中的特殊字符,因此,除非沒有歧義,否則需要對其進行轉義。 反引號是PS轉義字符。 您也可以在正則表達式中轉義$
,但這不是必需的。
作為最后一步,我們where
刪除空字符串(即不匹配項)。 以這種方式進行處理意味着我們只需要應用一次正則表達式,而不是在第一次過濾和第二次替換時應用兩次。
PowerShell操作員也可以直接在列表上工作。 因此,以上內容甚至可以縮短:
$vhdlist -replace "^UVHD-(S-[\d-]*)\.vhdx$","`$1" | where { $_ -gt "" }
較短的版本僅適用於實際字符串或對象列表,這些字符串或對象在調用.ToString()
時會產生正確的結果。
正則表達式細分:
^ # start-of-string anchor (?: # begin non-capturing group (either...) UVHD- # 'UVHD-' ( # begin group 1 S-[\d-]* # 'S-' and however many digits and dashes ) # end group 1 \.vhdx # '.vhdx' | # ...or... .* # anything else ) # end non-capturing group $ # end-of-string anchor
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.