另一个PowerShell
+ RegEx
进退两难的问题。
尝试解析包含脚本文件的文件夹/目录。找到包含变量设置的脚本,并输出脚本文件名以及分配给变量的值。
我看到的规则是:
MVL
开头,可能是也可能不是
前面有一个或多个空格。;
)结束。',
MVL
步骤显示变量值。我需要捕获的是脚本文件的名称,以及变量SRCFILE
,SERVER
,TARGETFILE
的值。
我正在寻找的数据是这样的:
MVL SRCFILE='\PATH\FOLDER\FILENAME.TXT ',SERVER='SERVERNAME ', TARGETFILE='TARGET.TXT ',PARM1=O,PARM2=N,PARM3=N,PARM4=Y,PARM5=N,PARM6=' ', PARM7=N,PARM8='NONE ',PARM8=' ', PARM9=00; Other lines I don't care about Could be blank lines * Comment lines will begin with asterisk, need to skip MVL SRCFILE='\PATH\FOLDER2\FILENAME'&1'.TXT ', SERVER='SERVERNAME2 ', TARGETFILE='TARGET2.TXT ',PARM1=O,PARM2=N,PARM3=N,PARM4=Y,PARM5=N,PARM6=' ', PARM7=N,PARM8='NONE ',PARM8=' ', PARM9=00;
我从RegEx模式开始,但现在完全失去了。我知道这只会从指定的文件中读取数据。
我最新的是这个,但我不能让它在连续的行中查看并捕获所需的值:
Select-String -Pattern "(?:^[\s]*?MVL\s*?SRCFILE=')(.*)(?:\s+?',)(?:.*$)" c:\scripts\Script1.scl
因此,如果样本数据位于Script1.scl
,我的输出将如下所示:
Script1.scl \PATH\FOLDER\FILENAME.TXT SERVERNAME TARGET.TXT
Script1.scl \PATH\FOLDER\FILENAME'&1'.TXT SERVERNAME2 TARGET2.TXT
答案 0 :(得分:1)
您可以通过两种方式让select-string搜索多个文件:
Select-String -Pattern "..." c:\scripts\*.sc1
或
Get-ChildItem c:\scripts\*.sc1 -recurse | Select-String -Pattern "..."
现在它搜索多个找到匹配的文件,它将输出一个具有以下属性的MatchInfo对象:
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property string Filename {get;}
IgnoreCase Property bool IgnoreCase {get;set;}
Line Property string Line {get;set;}
LineNumber Property int LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property string Path {get;set;}
Pattern Property string Pattern {get;set;}
您可以像这样提取文件名和正则表达式捕获组:
Select-String -Pattern "..." c:\scripts\*.sc1 | Select Filename,
@{n='ServerName';e={$_.matches.groups[1].Value}}
答案 1 :(得分:0)
这是最终的脚本:
## Folders to check
$TargetFolder1 = “C:\scripts”
$path = $TargetFolder1 + "\*.scl"
$regex = "(?:^[\s]*?MVL\s*?SRCFILE=')"
$scriptFiles=Select-String -Path $path -Pattern $regex | ForEach-Object {$_}
$varObjs = @()
foreach($file in $scriptFiles)
{
$currentFile = [io.file]::readalltext($file.Path) #-replace "[\r\n]", " "
$regex = "(?smi)(?:^[\s]*?MVL\s*?SRCFILE=')([^']+)\s*?'\s*?,\r?\n?(?:\s*?SERVER='([^']+)\s*?'\s*?,\r?\n?)?(?:\s*?TARGETFILE='([^']+)\s*?'\s*?,)?"
$b = select-string -InputObject $currentFile -AllMatches -Pattern $regex
for($i = 0; $i -le $b.Matches.Count-1; $i++)
{
$varObj = New-Object System.Object
$varObj | Add-Member -MemberType NoteProperty -Name ScriptName -Value $file.Path
$varObj | Add-Member -MemberType NoteProperty -Name SrcFile -Value $b.Matches[$i].Groups[1].value
$varObj | Add-Member -MemberType NoteProperty -Name Server -Value $b.Matches[$i].Groups[2].value
$varObj | Add-Member -MemberType NoteProperty -Name TargetFile -Value $b.Matches[$i].Groups[3].value
$varObjs += $varObj
}
}
$varObjs | Export-Csv -Delimiter "`t" -path c:\Test\Results.txt
exit