【问题标题】:Returning matched regex & Select-object properties of file where expression matched返回表达式匹配的文件的匹配正则表达式和选择对象属性
【发布时间】:2023-04-04 17:29:01
【问题描述】:

我正在尝试匹配正则表达式并返回匹配的表达式和正则表达式为真的文件的对象属性。

$pattern1 = regex1

$pattern2 = regex2

Get-ChildItem -Recurse -file -force -path "C:\" | ?{ findstr.exe /mprc:. $_.FullName } | where { $_ | Select-String -pattern $pattern1, $pattern2}  | Select-Object -Property FullName, CreationTime, LastWriteTime, Matched regex $pattern* | export-csv -Path c:\temp\Found.csv -NoTypeInformation

我可以使用:

Get-ChildItem -Path $path -Recurse -Force -Exclude *.*db, *.jpg, *.xps, *.msg, *.bmp, *.xfdl, *.ppt, *.dll, *.rs, *.evtx, *.dat.LOG1, *.dat.LOG2, *.log, *.dat, *.jfm, *.lock, *.pem -ErrorAction $erroractionpref | Select-String -pattern $pattern3, $pattern4 | Select-Object Path, FullName, Extension, BaseName, LineNumber, line, LastWriteTime

但是,我一直无法输出正则表达式匹配的字符串以及文件的对象属性。

示例输出:FullName、CreationTime、LastWriteTime、MatchedRegex$Pattern、Extension、BaseName

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    你没有说你有什么问题。您没有显示错误并解释您的代码问题。

    如果您尝试对纯文本文件以外的任何内容执行此操作,这将永远不会起作用。

    当你在这两种情况下都可以使用 Select-String 时,你为什么还要调用一个 exe?
    为什么要混合别名?

    这有什么期待……

    Matched regex $pattern* 
    

    ... Select-Object 永远不会知道这是什么,因此会失败。您必须在 Select 中使用合法属性(或计算属性)。

    运行您的代码,稍作修改,返回指定的正则表达式模式的结果。

    Findstr details

    # /m Prints only the file name if a file contains a match. 
    # /p Skips files with non-printable characters. 
    # /r Processes search strings as regular expressions. This is the default setting. 
    # /c:<String> Uses the specified text as a literal search string.
    
    $pattern1 = 'localhost'
    $pattern2 = 'COMPUTERNAME'
    
    Get-ChildItem -Recurse -file -force -path "E:\Temp" | 
    Where-Object { findstr.exe /mprc:. $PSItem.FullName } | 
    where-Object { $PSItem | Select-String -pattern $pattern1, $pattern2 }  | 
    Select-Object -Property FullName, CreationTime, LastWriteTime
    
    # Results
    
    FullName                                       CreationTime          LastWriteTime        
    --------                                       ------------          -------------        
    E:\Temp\available13.html.2019-03-26_081523.bak 4/1/2019 9:22:45 AM   3/27/2019 11:37:33 PM
    E:\Temp\hostlist.txt                           3/27/2019 11:36:53 PM 3/27/2019 11:37:33 PM
    E:\Temp\index.html.2019-03-26_081538.bak       4/1/2019 9:22:49 AM   3/27/2019 11:37:33 PM
    E:\Temp\Servers.txt                            5/8/2019 2:52:29 PM   5/10/2019 3:52:20 PM 
    

    留下最后一点...

    Matched regex $pattern* 
    

    会给你这个...

    $Error | Format-List -Force
    
    
    Exception             : System.Management.Automation.RuntimeException: The variable '$pattern' cannot be retrieved because it has not been set.
                               at System.Management.Automation.VariableOps.GetVariableValue(VariablePath variablePath, ExecutionContext 
                            executionContext, VariableExpressionAst varAst)
                               at System.Management.Automation.Interpreter.FuncCallInstruction`4.Run(InterpretedFrame frame)
                               at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
    TargetObject          : pattern
    CategoryInfo          : InvalidOperation: (pattern:String) [], RuntimeException
    FullyQualifiedErrorId : VariableIsUndefined
    ErrorDetails          : 
    InvocationInfo        : System.Management.Automation.InvocationInfo
    ScriptStackTrace      : at <ScriptBlock>, <No file>: line 4
    PipelineIterationInfo : {}
    PSMessageDetails      : 
    

    OP 后续更新

    # Change the select to all possible properties ...
    
    $pattern1 = 'localhost'
    $pattern2 = 'COMPUTERNAME'
    
    Get-ChildItem -Recurse -file -force -path "E:\Temp" | 
    Where-Object { findstr.exe /mprc:. $PSItem.FullName } | 
    where-Object { $PSItem | Select-String -pattern $pattern1, $pattern2 }  | 
    Select-Object -Property *
    

    ...您将看到它永远不会返回,因此您无法检索它,因为它永远不会在您的代码中传递,并且无法通过您编码的方式返回。

    您还必须考虑到该模式匹配可以是您传入的一个或多个模式,因此,它不是每行单个条目,而是一个数组。因此,现在您需要决定当所有模式都匹配时,您希望该输出的外观。

    例如,修改代码以处理捕获该模式,确实会给出输出...

    (现在,这只是一个快速的组合,并不优雅。)

    $pattern1 = 'localhost'
    $pattern2 = 'COMPUTERNAME'
    
    Get-ChildItem -Recurse -file -force -path "E:\Temp" | 
    Where-Object { findstr.exe /mprc:. $PSItem.FullName } | 
    where-Object { $PatternMatch = (Select-String -pattern $pattern1, $pattern2 -Path $PSItem.FullName )
    Select-String -pattern $pattern1, $pattern2 -Path $PSItem.FullName 
    }  | 
    Select-Object -Property FullName, CreationTime, LastWriteTime, 
    @{Name = 'PatternMatch';Expression = {$PatternMatch.Pattern}}
    
    # Results
    
    FullName                                       CreationTime          LastWriteTime         PatternMatch             
    --------                                       ------------          -------------         ------------             
    E:\Temp\available13.html.2019-03-26_081523.bak 4/1/2019 9:22:45 AM   3/27/2019 11:37:33 PM {COMPUTERNAME, localhost}
    E:\Temp\hostlist.txt                           3/27/2019 11:36:53 PM 3/27/2019 11:37:33 PM {COMPUTERNAME, localhost}
    E:\Temp\index.html.2019-03-26_081538.bak       4/1/2019 9:22:49 AM   3/27/2019 11:37:33 PM {COMPUTERNAME, localhost}
    E:\Temp\Servers.txt                            5/8/2019 2:52:29 PM   5/10/2019 3:52:20 PM  localhost 
    

    ...现在,这是您想要的最后一列的外观还是您想要每个模式匹配一​​行,所以,所有的东西都将是每列一个条目?

    如果您正在查看 1:1 比赛,即每次比赛多次显示文件,那么您最终需要明确的循环工作。

    例如:

    $pattern1 = 'localhost'
    $pattern2 = 'COMPUTERNAME'
    
    Get-ChildItem -Recurse -file -force -path "E:\Temp" | 
    Where-Object { findstr.exe /mprc:. $PSItem.FullName } | 
    ForEach { 
        Select-String -pattern $pattern1, $pattern2 -Path $PSItem.FullName | 
        Select-Object -Property Path, Pattern, 
        @{Name = 'CreationDate';Expression = {(Get-ChildItem -Path $PSItem.Path).CreationTime}},
        @{Name = 'LastWriteTime';Expression = {(Get-ChildItem -Path $PSItem.Path).LastWriteTime}}
    } 
    
    
    # Results
    
    Path                                           Pattern      CreationDate          LastWriteTime        
    ----                                           -------      ------------          -------------        
    E:\Temp\available13.html.2019-03-26_081523.bak COMPUTERNAME 4/1/2019 9:22:45 AM   3/27/2019 11:37:33 PM
    E:\Temp\available13.html.2019-03-26_081523.bak localhost    4/1/2019 9:22:45 AM   3/27/2019 11:37:33 PM
    E:\Temp\hostlist.txt                           COMPUTERNAME 3/27/2019 11:36:53 PM 3/27/2019 11:37:33 PM
    E:\Temp\hostlist.txt                           localhost    3/27/2019 11:36:53 PM 3/27/2019 11:37:33 PM
    E:\Temp\index.html.2019-03-26_081538.bak       COMPUTERNAME 4/1/2019 9:22:49 AM   3/27/2019 11:37:33 PM
    E:\Temp\index.html.2019-03-26_081538.bak       localhost    4/1/2019 9:22:49 AM   3/27/2019 11:37:33 PM
    E:\Temp\Servers.txt                            localhost    5/8/2019 2:52:29 PM   5/10/2019 3:52:20 PM 
    

    【讨论】:

    • 我的目标是将“匹配模式”添加到上面示例中的#Results 表中。这样,当我输出到 csv 时,我可以知道两个正则表达式中的哪一个匹配一个字符串,以及哪个字符串与正则表达式之一匹配。全名、CreationTime、LastWriteTime、匹配模式
    • 您的底部示例正是我想要的。谢谢。
    • 不用担心。很高兴它有帮助。
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2013-07-05
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多