2

另一个PowerShell+RegEx困境。试图解析包含脚本文件的文件夹/目录。找到包含变量设置的脚本,并输出脚本文件名以及分配给变量的值。

我看到的规则是:

  • 所需的步骤将始终以MVL可能或可能不以 1 个或多个空格开头。
  • 该步骤以冒号 ( ;) 结束。
  • 赋值结束于',
  • 需要显示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
4

2 回答 2

1

您可以通过两种方式让选择字符串搜索多个文件:

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}}
于 2013-09-13T18:46:16.063 回答
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
于 2013-09-24T20:19:07.640 回答