递归搜索目录以查找内容与正则表达式匹配的文件,并将匹配文件的路径收集到数组中
Recursively search a directory for files whose content matches a regex and collect the paths of matching files in an array
$locations = Get-ChildItem $readLoc -recurse | ? {!$_.psiscontainer} | select-object name | %{$e = $_.name; get-content $e}
$array = @()
for($i = 0; $i -lt $locations.length; $i++){
#if($locations.name[$i].length -eq "9"){
$paths = Resolve-Path $locations.fullname[$i]
$paths.path
get-content $locations.name[$i]
#$array += $paths.path
#}
}
我需要遍历文件系统中的每个文件并打开每个文件。我正在检查文件中的字符串是否与正则表达式匹配,然后将该文件的完整路径输出到数组中。
但是,$locations
不接受获取内容。
获取内容:找不到路径
'C:\Users\xxxxxx\Documents\files\powershell\OWASP_ApplicationThreatModeling.docx'
because it does not exist.
At line:1 char:89
+ ... .psiscontainer} | select-object name |%{$e = $_.name; get-content $e}
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\p61782...atModeling.docx:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand.
正如 TheMadTechnician 所建议的,使用 Select-String
执行正则表达式匹配更有效:
$locations = Get-ChildItem $readLoc -File -Recurse |
Select-String -List -Pattern '^\d{3}-?\d{2}-?\d{4}$' |
Select-Object -ExpandProperty Path
注:
- 传递给 -Pattern
的正则表达式是 linked to in a comment.
的简化版本
请注意正则表达式如何包含在 '...'
而不是 "..."
中,以防止 PowerShell 无意地 预先 解释字符串。
Get-ChildItem $readLoc -File -recurse
递归枚举目标目录子树中的所有文件。开关 -File
(连同它的对应物,-Directory
)在 PSv3+ 中可用,并且不需要 ? {!$_.psiscontainer}
过滤器。
Select-String
可以对通过 Get-ChildItem
传输的文件的 content 进行操作,并默认执行正则表达式匹配:
-List
告诉 Select-String
仅 return 来自每个输入文件(如果有)的 第一个 匹配项。
Select-String
returns 匹配信息对象 .Path
属性 包含完整路径输入文件的路径,因此 Select-Object -ExpandProperty Path
用于仅输出包含至少 1 个匹配项的任何文件的路径。
总体而言,变量 $locations
因此接收到那些文件的完整路径 数组 ,其中至少有 1 行与感兴趣的正则表达式匹配。
请注意,如果输出包含超过 1 个元素,PowerShell 会自动收集 数组 中命令的输出。
至于你尝试了什么:
您的直接问题是您将 .Name
- 即一个文件 name - 传递给了 Get-Content
而不是 .FullName
.
此外,您的明显意图是在数组 $locations
中收集 文件信息对象 ,而您的管道实际上产生了 所有文件的内容(作为行数组)。
您需要与 FullName
属性 合作。现在您正在使用 Select-Object
命令删除它。
$locations = Get-ChildItem $readLoc -recurse | ? {!$_.psiscontainer}
for($i = 0; $i -lt $locations.length; $i++){
$locations[$i].fullname
get-content $locations[$i].fullname
}
$locations = Get-ChildItem $readLoc -recurse | ? {!$_.psiscontainer} | select-object name | %{$e = $_.name; get-content $e}
$array = @()
for($i = 0; $i -lt $locations.length; $i++){
#if($locations.name[$i].length -eq "9"){
$paths = Resolve-Path $locations.fullname[$i]
$paths.path
get-content $locations.name[$i]
#$array += $paths.path
#}
}
我需要遍历文件系统中的每个文件并打开每个文件。我正在检查文件中的字符串是否与正则表达式匹配,然后将该文件的完整路径输出到数组中。
但是,$locations
不接受获取内容。
获取内容:找不到路径
'C:\Users\xxxxxx\Documents\files\powershell\OWASP_ApplicationThreatModeling.docx'
because it does not exist.
At line:1 char:89
+ ... .psiscontainer} | select-object name |%{$e = $_.name; get-content $e}
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\p61782...atModeling.docx:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand.
正如 TheMadTechnician 所建议的,使用 Select-String
执行正则表达式匹配更有效:
$locations = Get-ChildItem $readLoc -File -Recurse |
Select-String -List -Pattern '^\d{3}-?\d{2}-?\d{4}$' |
Select-Object -ExpandProperty Path
注:
- 传递给 -Pattern
的正则表达式是 linked to in a comment.
的简化版本
请注意正则表达式如何包含在 '...'
而不是 "..."
中,以防止 PowerShell 无意地 预先 解释字符串。
Get-ChildItem $readLoc -File -recurse
递归枚举目标目录子树中的所有文件。开关-File
(连同它的对应物,-Directory
)在 PSv3+ 中可用,并且不需要? {!$_.psiscontainer}
过滤器。Select-String
可以对通过Get-ChildItem
传输的文件的 content 进行操作,并默认执行正则表达式匹配:-List
告诉Select-String
仅 return 来自每个输入文件(如果有)的 第一个 匹配项。
Select-String
returns 匹配信息对象.Path
属性 包含完整路径输入文件的路径,因此Select-Object -ExpandProperty Path
用于仅输出包含至少 1 个匹配项的任何文件的路径。
总体而言,变量 $locations
因此接收到那些文件的完整路径 数组 ,其中至少有 1 行与感兴趣的正则表达式匹配。
请注意,如果输出包含超过 1 个元素,PowerShell 会自动收集 数组 中命令的输出。
至于你尝试了什么:
您的直接问题是您将
.Name
- 即一个文件 name - 传递给了Get-Content
而不是.FullName
.此外,您的明显意图是在数组
$locations
中收集 文件信息对象 ,而您的管道实际上产生了 所有文件的内容(作为行数组)。
您需要与 FullName
属性 合作。现在您正在使用 Select-Object
命令删除它。
$locations = Get-ChildItem $readLoc -recurse | ? {!$_.psiscontainer}
for($i = 0; $i -lt $locations.length; $i++){
$locations[$i].fullname
get-content $locations[$i].fullname
}