Powershell正则表达式:得不到匹配'字符串的一部分?

时间:2014-11-03 22:31:03

标签: regex powershell batch-file

我对powershell不太满意而且有问题。

我有一个powershell脚本调用批量文件来安装备份映像(shadowprotect),对挂载的映像运行chkdsk,卸载映像并返回。

批处理文件处理的所有输出都返回到我的powershell脚本。 我试图解析这个问题,以取消所有进展'由chkdsk命令生成的行,chkdsk似乎没有任何方法可以抑制此输出(在大型磁盘映像上我最终会有数百个进度行)。

我可以创建正则表达式来捕捉所有' Progress'行并将它们放到我的日志文件中,但是我无法弄清楚语法会给我提供与我的正则表达式不匹配的所有内容。

我尝试解析的返回值的非常简短的示例:

Try to mount d:\backups\colt\F_VOL-b001-i453-cd.spi
Mounting image chain "D:\Backups\colt\F_VOL-b001.spf|D:\Backups\colt\F_VOL-b001-i014-cd-cw.spi|D:\Backups\colt\F_VOL-b001-i018-cd.spi|D:\Backups\colt\F_VOL-b001-i022-cd.spi|D:\Backups\colt\F_VOL-b001-i026-cd.spi|D:\Backups\colt\F_VOL-b001-i030-cd.spi|D:\Backups\colt\F_VOL-b001-i445-cd.spi|D:\Backups\colt\F_VOL-b001-i449-cd.spi|D:\Backups\colt\F_VOL-b001-i453-cd.spi"

The type of the file system is NTFS.
Volume label is Local Disk - single.

WARNING!  F parameter not specified.
Running CHKDSK in read-only mode.

Stage 1: Examining basic file system structure ...
Progress: 0 of 4320 done; Stage:  0%; Total:  0%; ETA:   0:00:14    
Progress: 0 of 4320 done; Stage:  0%; Total:  0%; ETA:   0:00:21 .  
Progress: 6 of 4320 done; Stage:  0%; Total:  0%; ETA:   0:01:10 .. 
Progress: 257 of 4320 done; Stage:  5%; Total:  2%; ETA:   0:01:47 ...
Progress: 769 of 4320 done; Stage: 17%; Total:  6%; ETA:   0:01:20    
Progress: 2817 of 4320 done; Stage: 65%; Total: 19%; ETA:   0:00:23 .  
Progress: 4320 of 4320 done; Stage: 100%; Total: 29%; ETA:   0:00:14 .. 


  4320 file records processed.                                                        

File verification completed.
Progress: 0 of 0 done; Stage: 99%; Total: 46%; ETA:   0:00:13 ...


  0 large file records processed.                                   

Progress: 0 of 0 done; Stage: 99%; Total: 46%; ETA:   0:00:13    


  0 bad file records processed.                                     


Stage 2: Examining file name linkage ...
Progress: 4322 of 4360 done; Stage: 99%; Total: 92%; ETA:   0:00:01 .  
Progress: 4340 of 4360 done; Stage: 99%; Total: 93%; ETA:   0:00:01 .. 
Progress: 4344 of 4360 done; Stage: 99%; Total: 97%; ETA:   0:00:01 ...
Progress: 4360 of 4360 done; Stage: 100%; Total: 97%; ETA:   0:00:01    


  4360 index entries processed.                                                       

Index verification completed.
Progress: 0 of 0 done; Stage: 99%; Total: 97%; ETA:   0:00:01 .  


  0 unindexed files scanned.                                        

Progress: 0 of 0 done; Stage: 99%; Total: 97%; ETA:   0:00:01 .. 


  0 unindexed files recovered.                                      


Stage 3: Examining security descriptors ...
Security descriptor verification completed.
Progress: 0 of 0 done; Stage: 100%; Total: 99%; ETA:   0:00:00 ...


  20 data files processed.                                           


Windows has scanned the file system and found no problems.
No further action is required.

 145500673 KB total disk space.
  15814844 KB in 748 files.
       180 KB in 22 indexes.
         0 KB in bad sectors.
     74721 KB in use by the system.
     65536 KB occupied by the log file.
 129610928 KB available on disk.

      4096 bytes in each allocation unit.
  36375168 total allocation units on disk.
  32402732 allocation units available on disk.
OK -  0 

Return value is 0 

我的脚本片段如下所示:

 # call batch file...
 $Out = c:\batch\Mount_and_Chkdsk_image_file.cmd $NewFilePath
 # append result of batch file to the log file, remove progress lines first...
 $Out -replace ("^Progress:.*$", "")
 Out-File -FilePath c:\batch\log\NewFileCheck.log  -Append -InputObject $Out

在上面的尝试中,由于我可以匹配进度线,我认为我只是替换它们,但没有替换发生。

(对于测试,我只用原始未过滤日志文件的文件读取替换了批处理文件调用:

   $FilePath = "c:\batch\test2.txt"
    $Out = [System.Io.File]::ReadAllText($filePath)

无论如何,由于替换不起作用,我使用google并尝试将select-string理解为选项,因为它需要正则表达式:

$Regex = 'Pattern:.*'
$Out | select-string -pattern $Regex -notmatch

这只是推出了所有的线条,没有过滤掉,我曾希望' notmatch'意味着一切都不匹配。我似乎不知道我如何改变正则表达式,我无法做到我需要做的事情。

尝试了很多关于主题的变体,例如:

#$Regex = '^((Progress:).*$)'
$Regex = '([?<!Progress:].*)'

$Out | Select-String -Pattern $Regex -AllMatches | %{$_.Matches } | %{$_.value} 

但我显然遗漏了一些东西。我原以为会有一个简单的功能,如果你可以选择某个字符串,你也可以选择在输出中没有这个选择。

任何人都可以请求帮助,我如何捕捉所有不匹配的行?

此致   布莱斯S.

2 个答案:

答案 0 :(得分:4)

当然,这可以做到。默认情况下,当您使用Get-Content加载文本文件时,它会将每行加载为字符串,整个文件将是一个字符串数组。您可以通过Where语句运行该语句,并使用-notmatch运算符来过滤掉事物。用法如下:

$ParsedData = Get-Content "c:\batch\test2.txt" | Where{$_ -notmatch "Progress:.*$"}

这会帮助$ ParsedData文件中与正则表达式"Progress:.*$"不匹配的所有行。

编辑:好的,您从脚本中获得的内容很可能是多行字符串。我所知道的最简单的方法就是简单地在新行上打破你的字符串来创建一个字符串数组。像这样:

$Out.Split("`n") | Where{$_ -notmatch "Progress:.*$"}

答案 1 :(得分:2)

$Out = $Out -replace ("^Progress:.*$", "")
Out-File -FilePath c:\batch\log\NewFileCheck.log  -Append -InputObject $Out

唯一的问题是-replace没有修改左侧值,它只返回结果,保持$Out不变,所以你必须确保将结果分配给$Out