我正在尝试生成一个经过整理的文本文件。使用一个实用程序,我可以列出好的和坏的媒体文件。我想提取一个坏媒体文件的列表,这样我就可以替换它们了。
在日志中,坏媒体文件如下所示。
Testing L:MUSIC--Finnegan's Wake.mp3...
First frame invalid
MPEG 2.0 Layer I, 16000 hz, Stereo, Crc: No, Length: 0:00
Invalid bytes at end: 4622724
Frames: 0
Errors: 1 (100.00%)
-- NOT OK --
好的文件在日志中是这样的。
Testing L:MUSIC80's Giga Hits Collection. Only Best Disco Hits (2013) - SMG1383. William Pitt - City Lights (Extended).mp3...
ID3v1 found: City Lights (Extended) (William Pitt / Euro Disco 80's)
ID3v2 found: 73205 Bytes
MPEG 1.0 Layer III, 320 kbit, 44100 hz, Stereo, Crc: No, Length: 5:10
Frames: 11831
-- Ok --
我正试图提取术语-- Not Ok --
使用ps命令
(Get-Content "c:workingMP3Test.log") -notmatch "-- Not Ok --" | Out-File "c:workingBad.txt"
它仍然返回所有歌曲,但没有-- Ok --
我只想以--Not Ok--
的歌曲标题结束
我认为你可能需要一个脚本来完成这项工作,因为你需要匹配最后一行,但你需要写块的第一行。这似乎很有效。
$curFile="";
foreach ($line in gc c:workingMP3Test.log){
if ($line.StartsWith("Testing ")){
$curFile = $line.Replace("Testing ","")
}
elseif ($line.StartsWith("-- NOT OK --")){
Write-Output $curFile
}
}
您需要将Get-Content的输出通过管道传输到where cmdlet中,例如:
Get-Content 'c:workingMP3Test.log' | ? {$_ -notmatch '-- Not Ok --'} | Out-File 'c:workingBad.txt'
最好还是使用Select-String cmdlet,因为它会更快:
Select-String 'c:workingMP3Test.log' -Pattern '-- Not Ok --' | Select -ExpandProperty line | Out-File 'c:workingBad.txt'
选择Sting将是实现这一目标的方法。特别是-Context
参数
捕获匹配行前后指定数量的行。
select-string "C:temptest.txt" -Pattern "-- NOT OK --" -SimpleMatch -Context 6,0).Context.Precontext
这将在比赛前返回6行。至少使用PowerShell 3.0,我们使用.Context.Precontext
仅从MatchInfo对象获取原始文本。
如果文件中有多个匹配项,则可能需要进行更多的后期处理。
Select-String
支持正则表达式,我们在这里使用的是而不是。为了确保将来不会出现意外匹配,您可以使用-SimpleMatch
。请说明此特定实例不需要它。
为了只匹配该块中的歌曲,我们可以进行一些后期处理
$result = (select-string C:temptest.txt -Pattern "-- NOT OK --" -SimpleMatch -Context 6,0).Context.Precontext
$result | where-object{$_ -match "Testing"} | ForEach-Object{$_ -replace "^testing (.*?).*$",'$1'}
在匹配的行中,我们选择与"测试"匹配的行。然后,使用regex,我们删除测试前缀和尾部句点。当然,这不是唯一的方法。