我试图在Select-String Commandlet中为powershell找到工作正则表达式,查找特定文本,该文本被标记为查看文本的开头,并从此处查找其他特定文本,直到找到最后一个文本。
带文字的文件示例:
[Begin Of_Header]
Some.Text="Text"
Some.Text="Text"
Serial=0X94PA
Some.Text="Text"
Some.Text="Text"
Timer=0
Some.Text="Text"
Some.Text="Text"
Tag.SM=00
Some.Text="Text"
Some.Text="Text"
Some.Text="Text"
Some.Text="Text"
Tag.OM=00
Some.Text="Text"
Some.Text="Text"
Some.Text="Text"
Tag.UC=00
Some.Text="Text"
Some.Text="Text"
Some.Text="Text"
Events=pd_exf1
Some.Text="Text"
Some.Text="Text"
Some.Text="Text"
Acp="My looking dynamic text"
Some.Text="Text"
Some.Text="Text"
Dir=6
Some.Text="Text"
Some.Text="Text"
WG=100
Some.Text="Text"
Some.Text="Text"
H=95.5
Some.Text="Text"
Some.Text="Text"
[Begin Of_Header]
Serial=0XZZZ
Timer=0
Some.Text="Text"
Some.Text="Text"
Tag.OM=00
Tag.UC=00
Some.Text="Text"
Some.Text="Text"
Events=pd_exf1
Acp="My looking dynamic text"
Dir=6
WG=100
H=95.5
[Begin Of_Header]
Serial=0XPPPP
Timer=0
Tag.SM=00
Some.Text="Text"
Some.Text="Text"
Tag.OM=00
Tag.UC=00
Some.Text="Text"
Some.Text="Text"
Events=pd_exf1
Acp="My looking dynamic text"
Dir=6
WG=100
H=95.5
在这种情况下,它应该寻找静态字 [Begin Of_Header] ,从这一点开始以 Serial = 开头并以 Acp =&#34;我看起来动态的文字&#34; 。并且Acp =可以具有各种值+序列。如果缺少值,例如缺少 Tag.SM = 00 ,则跳过此组中的搜索并跳转到下一个 [Begin Of_Header] 并再次开始分析。< / p>
结果应该是这样的:
[Begin Of_Header]
Serial=0X94PA
Timer=0
Tag.SM=00
Tag.OM=00
Tag.UC=00
Events=pd_exf1
Acp="My looking dynamic text"
[Begin Of_Header]
Serial=0XPPPP
Timer=0
Tag.SM=00
Tag.OM=00
Tag.UC=00
Events=pd_exf1
Acp="My looking dynamic text"
我找到了类似的here,但并没有完全按照我的意愿行事。
此功能也不会按预期工作,因为它不会排除损坏的完全匹配顺序:
Select-String -LiteralPath "C:\myfile.txt" -Pattern "\[Begin Of_Header\]|Serial=|Timer=|Tag.SM=|Tag.OM=|Tag.UC=|Events=|Acp=" | Select-Object LineNumber,Line
答案 0 :(得分:0)
如果您愿意尝试除正则表达式之外的其他内容。我只是创建一个具有一些if
条件的数组并抓住我需要的东西。
像这样......
不确定这是否是最有效的代码,但它有效..
$content = get-content "C:\myfile.txt"
$serial = @()
$timer = @()
$sm = @()
$om = @()
$uc = @()
$events = @()
$acp = @()
Foreach($line in $content){
If ($line -match "Serial="){$serial += $line}
If ($line -match "Timer="){$timer += $line}
If ($line -match "Tag.SM="){$sm += $line}
If ($line -match "Tag.OM="){$om += $line}
If ($line -match "Tag.UC="){$uc += $line}
If ($line -match "Events="){$events += $line}
If ($line -match "Acp="){$acp += $line}
}
"[Begin Of_Header]"
$serial[0]
$timer[0]
$sm[0]
$om[0]
$uc[0]
$events[0]
$acp[0]
"[Begin Of_Header]"
$serial[2]
$timer[2]
$sm[2]
$om[2]
$uc[2]
$events[2]
$acp[2]
答案 1 :(得分:0)
正则表达式很复杂,但由于元素的顺序是固定的,我没有看到问题。
$Header = '[Begin Of_Header]'
$RE = [RegEx]'(?smi)(^Serial=.*?$).*(^Timer=.+?$).*(^Tag\.SM=.+?$).*(^Tag\.OM=.+?$).*(^Tag\.UC=.+?$).*(^Events=.+?$).*(^Acp=.+?$)'
(Get-Content .\myfile.txt -raw) -split [RegEx]::Escape($Header)|
Select-String $RE | ForEach-Object{
$Header
for($i=1;$i -lt 8;$i++){$_.matches.groups[$i].value}
""
}
示例输出:
> Q:\Test\2017\09\10\SO_46139332.ps1
[Begin Of_Header]
Serial=0X94PA
Timer=0
Tag.SM=00
Tag.OM=00
Tag.UC=00
Events=pd_exf1
Acp="My looking dynamic text"
[Begin Of_Header]
Serial=0XPPPP
Timer=0
Tag.SM=00
Tag.OM=00
Tag.UC=00
Events=pd_exf1
Acp="My looking dynamic text"
(?smi)
建议RE使用
s修饰符:单行。 Dot匹配换行符
m修饰符:多行。导致^和$匹配每行的开头/结尾(不仅是字符串的开头/结尾)
(^Serial=.*?$).*