我正在使用Windows 2003 Server x86,Powershell 1.0并且遇到了令人头疼的问题。当我尝试执行下面的脚本时,我收到一个错误:
Error "=" operator: System error. (Fehler beim "="-Operator: Systemfehler.)
+ $data = <<<< Get-Content $log | % {
这是这个脚本:
$log = "C:\log file.txt"
$linePrefix = "PROCESS THIS LINE"
$trimStart = 25 #chars to ignore in the beginning
$started = 0
$data = Get-Content $log | % {
if ($_.length -ge $trimstart) {
$linedata = $_.substring($trimstart);
$timesline = $linedata.startswith($lineprefix);
if ($started -eq 0 -and $timesline) {
$started = 1;
}
if ($started) {
if ($timesline) {
$line = $linedata.substring($lineprefix.length).trimstart();
if ($line.contains(": ")) {
write-output $line
}
} else {
break;
}
}
}
}
但是,如果我在没有$data =
赋值的情况下执行它,它会完美运行并返回我预期的值。我也尝试过以下陈述
$data = (...)
$data = $(...)
并使用表达式声明函数但没有成功。
你能不能给我一个提示,为什么会这样?
更新:我尝试在分配符号前后删除空格并出现类似错误,但现在powershell不喜欢$data=G
字符串
Error "=" operator: System error (Fehler beim "="-Operator: Systemfehler.)
At C:\kosmo\scripts\ps\test.ps1:60 Symbol:7
+ $data=G <<<< et-Content $log | % {
答案 0 :(得分:0)
我已将您的代码转换为将返回String对象的函数。所以你可以按如下方式运行它:
$data = Parse-LogFile
您需要先将该功能导入到shell中,您只需复制并粘贴它即可。
Function Parse-LogFile
{
$log = gc "C:\log file.txt"
$linePrefix = "PROCESS THIS LINE"
$trimStart = 25 #chars to ignore in the beginning
$started = 0
$ReturnText = New-Object System.Text.StringBuilder
foreach ( $line in $log )
{
if ($_.length -ge $trimstart)
{
$linedata = $_.substring($trimstart);
$timesline = $linedata.startswith($lineprefix);
if ($started -eq 0 -and $timesline)
{
$started = 1;
}
if ($started)
{
if ($timesline)
{
$line = $linedata.substring($lineprefix.length).trimstart();
if ($line.contains(": "))
{
$ReturnText.Append($line)
$ReturnText.AppendLine()
}
}
else
{
break;
}
}
}
}
Retrun $ReturnText.ToString()
}
答案 1 :(得分:0)
虽然我无法在我的计算机上重现您的问题,但我认为问题可能与您在分配期间在管道中使用break
有关。作为第一个测试,如果您删除break
,它会改变一些事情吗?
假设这确实是问题,您可以稍微重构以避免直接进行分配。相反,您可以在循环内部构建$data
变量。
$log = ".\logfile.log"
$linePrefix = "PROCESS THIS LINE"
$trimStart = 25 #chars to ignore in the beginning
$started = 0
$data = @() # initialize blank data array
Get-Content $log | % {
if ($_.length -ge $trimstart) {
$linedata = $_.substring($trimstart);
$timesline = $linedata.startswith($lineprefix);
if ($started -eq 0 -and $timesline) {
$started = 1;
}
if ($started) {
if ($timesline) {
$line = $linedata.substring($lineprefix.length).trimstart();
if ($line.contains(": ")) {
# add to your result here
$data += $line
}
} else {
break;
}
}
}
}
现在$data
包含您想要的内容。这可能不是性能最佳的代码,具体取决于您期望的结果数量,但它可能会给您一个开始。
答案 2 :(得分:0)
非常感谢您的提示!可惜,但没有任何建议确实解决了我的问题。 最有帮助的是提示拉特金关于休息行为。经过一些reading我发现,在Foreach-Object cmdlet中,由%,别名或中断语句停止整个脚本
function getFilteredResult {
1..50 | % {
if ($_ -le 20) {
if (($_ % 2) -eq 0) {
write-output $_;
}
} else {
break; #terminates whole script, you don't even get "after got result"
#continue; #save result as break
}
}
}
Write-Host "before getting result"
$result = getFilteredResult
$result | % {$i=0}{ ++$i; Write-Host "$i) $_" }
Write-Host "after got result"
输出仅显示before getting result
。从那里我得出结论,没有办法在Powershell 1.0中做我想要的!所以我发现a way在我旧的2003服务器上安装Powershell 2.0(tip如何卸载Powershell 1.0之前;顺便说一句,我的Windows更新名称为KB926140-v5)。
好的,错误消失了。但我仍然没有想要的结果?!在旅程结束时,我发现非常useful post,并在下面写了
function getFilteredResult {
Try {
1..50 | % {
if ($_ -le 20) {
if (($_ % 2) -eq 0) {
write-output $_;
}
} else {
#break; #terminates whole script, you don't even get "after got result"
#continue; #terminates whole script, you don't even get "after got result"
throw "terminated pipeline!"
}
}
} Catch {
#ignore terminated pipeline exception
}
}
Write-Host "before getting result"
$result = getFilteredResult
$result | % {$i=0}{ ++$i; Write-Host "$i) $_" }
Write-Host "after got result"
得到了答案:
before getting result
1) 2
2) 4
3) 6
4) 8
5) 10
6) 12
7) 14
8) 16
9) 18
10) 20
after got result
解释
如果我使用foreach
语句,我可以使用break来估计行为,但是我正在处理大型日志文件,而foreach语句将整个文件读入内存,而ForEach-Object cmdlet则逐个处理行。我不确定Get-Content cmdlet,也许它还会读取整个文件以返回它,但我已经写下了我自己的cmdlet Get-Content-Reversed来读取文件末尾的行,这就是为什么我很漂亮确定它没有