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 文件,以便可能找到解决方案。
- 感谢@Otter 让我度过难关。我有一个使用此函数的先前脚本,但出于某种原因我无法按预期执行该函数。我以前的脚本和这个脚本之间的区别是 $_.Fullname
帮助很大!
听起来您需要一个 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),如上图
.Matches
是 System.Text.RegularExpressions.Match
个实例的集合(如果 -AllMatches
开关,则只能有 多个 个元素已通过),每个的 .Value
属性 包含与整体模式匹配的 文本 。
如果 -Pattern
正则表达式包含 捕获组 ((...)
),每个 Match
实例的 .Groups
集合 - 本身由 Match
个实例组成 - 包含这些组捕获的内容,从索引 1
开始; .Value
属性 再次包含捕获的 text.
我正在构建一个脚本,该脚本将访问大量文件并提取特定字符串以便分配为变量。
所有文件的字符串都相似,这不是问题所在。我能够使这个过程作为一个单独的事件运行(定义一个单一的源文件)
$hostname_import = select-string .\test.txt -Pattern 'hostname ABC-.+'
$hostname = $hostname_import -replace '.+ ',''
上面将输出目标文件中标识的特定主机名(第二个功能是 trim 主机名和 space 一词)然后我可以使用它继续使用变量根据需要执行各种操作。
我遇到的问题是在 foreach 循环中执行此函数,以便我可以获取初始文件 - 执行 select-string 函数(或类似函数),然后在循环中执行数据修改不出所料。
对于上下文 - 我正在查看配置文件 - 并根据这些配置构建一个单独的文件以报告发现结果 - 部分报告构建需要设备的主机名。
--编辑 1: 在咨询了我的橡皮鸭之后,我将尝试将这些文件导入为 CSV 文件,以便可能找到解决方案。
- 感谢@Otter 让我度过难关。我有一个使用此函数的先前脚本,但出于某种原因我无法按预期执行该函数。我以前的脚本和这个脚本之间的区别是 $_.Fullname
帮助很大!
听起来您需要一个 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),如上图
.Matches
是System.Text.RegularExpressions.Match
个实例的集合(如果-AllMatches
开关,则只能有 多个 个元素已通过),每个的.Value
属性 包含与整体模式匹配的 文本 。如果
-Pattern
正则表达式包含 捕获组 ((...)
),每个Match
实例的.Groups
集合 - 本身由Match
个实例组成 - 包含这些组捕获的内容,从索引1
开始;.Value
属性 再次包含捕获的 text.