我有这个perl代码,我试图转换为powershell。
foreach my $f ( @file_list ) {
if( $f =~ /^([d]+)_${base_ver}_([d]{4}).zip$/i ){
$pfile = $f;
( $pnum, $pdate ) = ( $pfile =~ /^([d]+)_${base_ver}_([d]{4}).zip$/i ); # need to convert
( $pmon, $pyear ) = ( $pdate =~ /^(dd)(dd)$/ ); # need to convert
if( ($patch_nbr == 0) || ($patch_nbr == $pnum) ) {
$fcnt++;
}
}
}
我在这里转换了大部分。
$file_list = Get-ChildItem -force $base_dir
$file_list | foreach-object {
if($_ -match "/^([d]+)_${base_ver}_([d]{4}).zip$/i"){
$pfile = $_
if($patch_nbr -eq 0 -or $pacth_nbr -eq $pnum){
$fcnt++
}
}
}
不太确定如何转换等于正则表达式的两个变量,或者是否有比我已经拥有的更好的方法将perl代码转换为powershell。
来自perl
的[mode]/pattern/[replace/][options]
语法不适用于PowerShell中的regex。
/^([d]+)_${base_ver}_([d]{4}).zip$/i
是
^([d]+)_${base_ver}_([d]{4}).zip$
(i
不需要,-match
默认解析为-imatch
(大小写i不敏感匹配)
要捕获号码前缀和日期,可以使用命名捕获组((?<name>pattern)
):
^(?<num>[d]+)_${base_ver}_(?<date>[d]{4}).zip$
你可以从$Matches["name"]
中获取匹配:
if($f -match "^(?<num>[d]+)_${base_ver}_(?<date>[d]{4}).zip$"){
$pfile = $f
$pnum = $Matches["num"]
$pdate = $Matches["date"]
$pmon = -join $pdate[0..1]
$pyear = -join $pdate[2..3]
}
您还可以更改regex模式以分别捕获月份和年份:
if($f -match "^(?<num>[d]+)_${base_ver}_(?<month>[d]{2})(?<year>[d]{2}).zip$"){
$pfile = $f
$pnum = $Matches["num"]
$pmon = $Matches["month"]
$pyear = $Matches["year"]
}
我会先放一个Where-Object
过滤器。这样就可以在后续的ForEach-Object
中使用$matches
集合,而不必在嵌套的if
语句中使用第二个-match
。如果您还将日期模式从(d{4})
更改为(d{2})(d{2})
,则可以在单个语句中分配$pnum
, $pmon
和$pyear
。还可以简化$fcnt
递增的条件。而不是检查$patch_nbr
是否等于两个值中的一个,你可以检查它是否包含在两个值的数组中。
Get-ChildItem -Force $base_dir |
Where-Object { $_ -match '^(d+)_${base_ver}_(d{2})(d{2}).zip$' } |
ForEach-Object {
$pnum, $pmon, $pyear = $matches[1..3]
if (0, $pnum -contains $patch_nbr) { $fcnt++ }
}
}
当然,如果你想做的只是计算与给定补丁号匹配的文件数量,你可以这样做:
$f = Get-ChildItem -Force $base_dir | Where-Object {
$_ -match '^(d+)_${base_ver}_d{4}.zip$' -and
0, $matches[1] -contains $patch_nbr
}
$fcnt = @($f).Count