我第一次用PowerShell编程,对它不太满意。我有一个包含许多行的文件,比如这一行";标记ABCDEFGH的AddItems失败,类型VT_R4:ItemID不在服务器地址空间中(c0040007("。我只想检索EFGH字符串。我首先尝试了.Substring()
方法,但它并没有真正起作用,因为我试图检索的所有字符串都不具有相同的长度。这个想法基本上是取出包含在";标签";以及"&";,但我不知道如何编码。
$log = get-content C:Logsmylog.txt
foreach ($line in $log) {
if ($line -like "*tag*") {
$line.substring(24,36)
$line | out-file -FilePath "C:LogsItemIDs.txt" -Append
}
}
下面是一个输入示例:
tag Z..ANTW@ENERGY@C605_RAIL4_MC_403
tag ANTW@CALI@CALLISTO@130LI513B.PV,
Z..ANTW@ENERGY@C605_RAIL4_MC_403
和ANTW@CALI@CALLISTO@130LI513B.PV
都是ABCDEFGH,而且第一个例子中缺少几个字母。
非常感谢您的帮助,我们将不胜感激!
使用-match
regex运算符测试给定字符串是否包含特定模式,然后使用$Matches
自动变量提取捕获的任何组:
if('tag ANTW@CALI@CALLISTO@130LI513B.PV,' -match 'tag ([^,]+),'){
$Matches[1]
}
您会发现上面语句的输出是字符串ANTW@CALI@CALLISTO@130LI513B.PV
,所以假设这就是您所需要的,只需输出即可将其添加到循环中,并将$Matches[1]
输出到文件:
foreach($line in $log){
if($line -match 'tag ([^,]+),'){
$Matches[1] |Out-File -FilePath C:LogsItemIDs.txt -Append
}
}
我相信我们可以找到简单字符串方法(如.SubString()
和.IndexOf()
(的排列和组合来实现这一点,但这样做总是需要输入字符串具有可靠的一致性。也就是说,使用你举的例子:
$String = "AddItems failed for tag ABCDEFGH, type VT_R4: The ItemID is not in the server address space (c0040007)"
$OutputString = $String.SubString($String.IndexOf("tag")+4)
$OutputString = ($OutputString -split ',')[0]
这假定单词";标签";总是在";EFGH";以及"总是跟踪它。并说找到标签的起始位置,再加4。然后使用-split
得到一个数组,但只给我第一个元素,它应该是"&";。
然而,与马蒂亚斯典型的好答案相似,我认为雷杰克斯更适合这一点(并非双关语(。然而,我喜欢使用环视:
我不知道这是否完美,也许它可以提炼。我不认为自己是RegEx专家。。。
$String = "AddItems failed for tag ABCDEFGH, type VT_R4: The ItemID is not in the server address space (c0040007)"
$String -match "(?!tag)w*(?=,)"
这应该返回:ABCDEFGH
。
简而言之,这意味着返回在";标签";以及"&";。
将其与您的原始代码结合在一起:
$log = Get-Content 'C:Logsmylog.txt'
$pattern = '(?<=tags{1}).*(?=,)'
ForEach ($line in $log) {
if ( $line -match $pattern ) {
$Matches[0] | Out-File -FilePath "C:LogsItemIDs.txt" -Append
}
}