当我在if
循环中调用foreach
comandlet时:
$spisok = Get-Content "OmConv79_2.txt" -TotalCount 100
foreach ($i in $spisok) {
#Write-Host $i
$i -match "^(.*)\t(.+)\t?(.*)?" |
foreach { $Matches[1] + "----" + $Matches[2] + "----" + $Matches[3] } |
if ($Matches[1] -eq "^\d\d.\d\d.\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d") {
$Matches[0]
}
}
我收到了这个错误:
if : The term 'if' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:7 char:9 + if ($Matches[1] -eq "^\d\d.\d\d.\d\d \d\d:\d\d:\d\d\.\d\d\d\d ... + ~~ + CategoryInfo : ObjectNotFound: (if:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
“if”无法识别?我糊涂了。怎么可能?
答案 0 :(得分:3)
您无法在管道中直接使用<{1}}语句。
您第二次使用if
不是循环,而是在管道中调用ForEach-Object
cmdlet 。
遗憾的是,foreach
cmdlet别名为ForEach-Object
,导致与foreach
关键字(循环结构)混淆。
要在管道中加入foreach
语句(有条件),根据您的需要,您有两种选择:
如果if
语句仅对输入执行过滤 - 有选择地 - 传递,请使用脚本块中的条件if
来电(别名:Where-Object
,where
)
如果?
语句也生成自定义输出,请将其放在if
调用的脚本块中(别名:ForEach-Object
,{ {1}})。
简化示例:
foreach
仅使用%
过滤解决方案:
# !! These BREAK - you cannot use `if` directly in a pipeline.
'line 1', 'line 2' | if ($_ -match '1') { $_ } # filtering only
'line 1', 'line 2' | if ($_ -match '1') { $_ + '!' } # filtering + custom output
使用Where-Object
过滤+自定义输出解决方案:
$ 'line 1', 'line 2' | Where-Object { $_ -match '1' }
line 1
至于您的代码:
据我所知(包括后面的评论), 可以
ForEach-Object
请注意使用单个管道,只需一次$ 'line 1', 'line 2' | ForEach-Object { if ($_ -match '1') { $_ + '!' } }
line 1!
调用即可处理每个输入行。
Get-Content "OmConv79_2.txt" -TotalCount 100 |
ForEach-Object { # process each line, represented as $_
if ($_ -match '^(.*)\t(.+)\t?(.*)?') {
# Is the first tab-separated field a date + time?
if ($Matches[1] -match '^\d\d.\d\d.\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d') {
$Matches[0] # Output the first 3 tab-separated fields.
} else {
# Output line with default date prepended
}
}
}
必须替换为ForEach-Object
以匹配-eq
正则表达式。
正则表达式是单引号,因此PowerShell的字符串插值不会妨碍。