select-string 在 for-each 循环中的使用

select-string use in a for-each loop

我正在构建一个脚本,该脚本将访问大量文件并提取特定字符串以便分配为变量。

所有文件的字符串都相似,这不是问题所在。我能够使这个过程作为一个单独的事件运行(定义一个单一的源文件)

$hostname_import = select-string .\test.txt -Pattern 'hostname ABC-.+'
$hostname = $hostname_import -replace '.+ ',''

上面将输出目标文件中标识的特定主机名(第二个功能是 trim 主机名和 space 一词)然后我可以使用它继续使用变量根据需要执行各种操作。

我遇到的问题是在 foreach 循环中执行此函数,以便我可以获取初始文件 - 执行 select-string 函数(或类似函数),然后在循环中执行数据修改不出所料。

对于上下文 - 我正在查看配置文件 - 并根据这些配置构建一个单独的文件以报告发现结果 - 部分报告构建需要设备的主机名。

--编辑 1: 在咨询了我的橡皮鸭之后,我将尝试将这些文件导入为 CSV 文件,以便可能找到解决方案。

帮助很大!

听起来您需要一个 Get-ChildItem,它将获取文件夹中的所有文件,然后将输出通过管道传输到一个 Foreach-Object 循环,该循环将引用每个文件。

请注意,我添加了 -recurse 开关,以防您也需要获取子文件夹文件。

试试下面的方法:

Get-Childitem -path "C:\PathToFolder" -recurse | Foreach-Object {
    $hostname_import = select-string $_.Fullname -Pattern 'hostname ABC-.+'
    $hostname = $hostname_import -replace '.+ ',''
    
    # The rest of your logic goes here
}

Select-String 可以通过其 -Path-LiteralPath 参数直接处理 多个 文件,作为 array 的路径 and/or 作为通配符表达式。

它不支持传递目录路径以处理其中的文件(更不用说递归),因此,为此您需要将 Get-ChildItem(可能带有 -Recurse)的结果通过管道传输到 Select-String 调用。

以下示例使用后一种技术,遍历当前目录子树中的所有 *.config 个文件:

Get-ChildItem -File -Recurse -Filter *.config |
  Select-String -Pattern 'hostname ABC-(.+)' |
   ForEach-Object {
     $sourceFilePath = $_.Path
     $hostName = $_.Matches[0].Groups[1].Value
   }

注意在正则表达式模式中使用捕获组 ((...)),它允许通过 Select-String 输出。这避免了 -replace 操作的需要;详情见底部。

请注意,每个文件可能会报告 多个 匹配项;如果您知道只有一个(或者只对第一个感兴趣),请将-List添加到Select-String调用以加快操作。


如何只提取匹配行/行部分的文本(字符串):

当您在字符串上下文中直接使用Select-String输出对象(类型Microsoft.PowerShell.Commands.MatchInfo)时例如 -replace,如果给出了文件参数,则生成的字符串表示包含 更多 而不仅仅是 行文本 ,因为输入文件路径添加到行文本之前,后跟 :;例如:
C:\path\to\file.config:hostname ABC-foo

仅提取行文本,直接作为字符串,使用.Line属性.

  • 注意:在 PowerShell (Core) 7+ 中,您现在可以要求 Select-String 直接 输出字符串(匹配行),方法是传递 -Raw切换。

仅提取正则表达式匹配的行部分,请使用.Matches 属性(n/a if the -SimpleMatch switch for literal substring matching is also passed),如上图

  • .MatchesSystem.Text.RegularExpressions.Match 个实例的集合(如果 -AllMatches 开关,则只能有 多个 个元素已通过),每个的 .Value 属性 包含与整体模式匹配的 文本

  • 如果 -Pattern 正则表达式包含 捕获组 ((...)),每个 Match 实例的 .Groups 集合 - 本身由 Match 个实例组成 - 包含这些组捕获的内容,从索引 1 开始; .Value 属性 再次包含捕获的 text.