转换为 Powershell
Converting to Powershell
我有这个 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 =~ /^(\d\d)(\d\d)$/ ); # 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 中的正则表达式。
因此,你的模式
/^([\d]+)_${base_ver}_([\d]{4})\.zip$/i
变成
^([\d]+)_${base_ver}_([\d]{4})\.zip$
(i
不需要,-match
默认解析为-imatch
(case-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]
}
您还可以更改正则表达式模式以单独捕获月份和年份:
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
我有这个 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 =~ /^(\d\d)(\d\d)$/ ); # 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 中的正则表达式。
因此,你的模式
/^([\d]+)_${base_ver}_([\d]{4})\.zip$/i
变成
^([\d]+)_${base_ver}_([\d]{4})\.zip$
(i
不需要,-match
默认解析为-imatch
(case-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]
}
您还可以更改正则表达式模式以单独捕获月份和年份:
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