用于搜索 excel 个文件的目录以查找仅搜索 1 个文件的字符串的 Powershell 脚本
Powershell script to search through a directory of excel files to find a string only searching through 1 file
我在 https://shuaiber.medium.com/ 上找到了这个脚本
我想用它在充满 excel 个文件的文件夹中查找某个字符串。
我遇到的问题是它基本上只搜索 1 个文件然后停止...
这是脚本
Function Search-Excel {
[cmdletbinding()]
Param (
[parameter(Mandatory, ValueFromPipeline)]
[ValidateScript({
Try {
If (Test-Path -Path $_) {$True}
Else {Throw "$($_) is not a valid path!"}
}
Catch {
Throw $_
}
})]
[string]$Source,
[parameter(Mandatory)]
[string]$SearchText
#You can specify wildcard characters (*, ?)
)
$Excel = New-Object -ComObject Excel.Application
Try {
$Source = Convert-Path $Source
}
Catch {
Write-Warning "Unable locate full path of $($Source)"
BREAK
}
$Workbook = $Excel.Workbooks.Open($Source)
ForEach ($Worksheet in @($Workbook.Sheets)) {
$Found = $WorkSheet.Cells.Find($SearchText) #What
If ($Found) {
$BeginAddress = $Found.Address(0,0,1,1)
#Initial Found Cell
[pscustomobject]@{
WorkSheet = $Worksheet.Name
Column = $Found.Column
Row =$Found.Row
Text = $Found.Text
Address = $BeginAddress
}
Do {
$Found = $WorkSheet.Cells.FindNext($Found)
$Address = $Found.Address(0,0,1,1)
If ($Address -eq $BeginAddress) {
BREAK
}
[pscustomobject]@{
WorkSheet = $Worksheet.Name
Column = $Found.Column
Row =$Found.Row
Text = $Found.Text
Address = $Address
}
} Until ($False)
}
Else {
Write-Warning "[$($WorkSheet.Name)] Nothing Found!"
}
}
$workbook.close($false)
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$excel)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()
Remove-Variable excel -ErrorAction SilentlyContinue
}
然后我会用
Get-ChildItem -路径 "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Select-对象-属性目录,名称| ForEach-Object { "{0}{1}" -f $.Directory, $.Name } |搜索-Excel -SearchText MyText
我知道它只能搜索 1 个文件,因为我查看了另一个文件并试图让它发回给我确认,但它不起作用。
如有任何帮助,我们将不胜感激。
您将需要在函数中包含一个循环,或者将函数放在 ForEach-Object
循环中。对于功能更改,您可以执行以下操作:
Function Search-Excel {
[cmdletbinding()]
Param (
[parameter(Mandatory, ValueFromPipeline)]
[ValidateScript({
Try {
If (Test-Path -Path $_) {$True}
Else {Throw "$($_) is not a valid path!"}
}
Catch {
Throw $_
}
})]
[string]$Source,
[parameter(Mandatory)]
[string]$SearchText
#You can specify wildcard characters (*, ?)
)
$Excel = New-Object -ComObject Excel.Application
ForEach($Path in $Source){
### <the rest of your existing code here, adjusted to work with $Path instead of $Source>
}
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$excel)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()
Remove-Variable excel -ErrorAction SilentlyContinue
}
或者,要使用您现有的函数,您可以这样做:
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm |
ForEach-Object { Search-Excel -Source $_.FullName -SearchText MyText }
那么让我们用你的命令来谈谈一些事情。
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Select-Object -Property Directory, Name | ForEach-Object { "{0}{1}" -f $.Directory, $.Name } | Search-Excel -SearchText MyText
如果我们将其分解成单独的部分(用竖线分隔),我们也许能够找出问题所在。第一部分 Get-ChildItem
仅查找匹配 *.xls
、*.xlsx
和 *.xlsm
的文件,因此已经排除了目录。那么,这个函数return到底是做什么的呢?如果您要查看对象类型,您会看到 System.IO.FileInfo
,它内置了一堆属性。其中之一是所需的完整文件路径,.FullName
.
目前,Search-Excel
设置为仅搜索一个文件。如果您想一次搜索多个文件,则需要在某处进行循环。在我看来,最简单的地方就是在函数之外,就像这样:
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Foreach-Object { Search-Excel -Source $_.FullName -SearchText MyText }
我在 https://shuaiber.medium.com/ 上找到了这个脚本 我想用它在充满 excel 个文件的文件夹中查找某个字符串。 我遇到的问题是它基本上只搜索 1 个文件然后停止...
这是脚本
Function Search-Excel {
[cmdletbinding()]
Param (
[parameter(Mandatory, ValueFromPipeline)]
[ValidateScript({
Try {
If (Test-Path -Path $_) {$True}
Else {Throw "$($_) is not a valid path!"}
}
Catch {
Throw $_
}
})]
[string]$Source,
[parameter(Mandatory)]
[string]$SearchText
#You can specify wildcard characters (*, ?)
)
$Excel = New-Object -ComObject Excel.Application
Try {
$Source = Convert-Path $Source
}
Catch {
Write-Warning "Unable locate full path of $($Source)"
BREAK
}
$Workbook = $Excel.Workbooks.Open($Source)
ForEach ($Worksheet in @($Workbook.Sheets)) {
$Found = $WorkSheet.Cells.Find($SearchText) #What
If ($Found) {
$BeginAddress = $Found.Address(0,0,1,1)
#Initial Found Cell
[pscustomobject]@{
WorkSheet = $Worksheet.Name
Column = $Found.Column
Row =$Found.Row
Text = $Found.Text
Address = $BeginAddress
}
Do {
$Found = $WorkSheet.Cells.FindNext($Found)
$Address = $Found.Address(0,0,1,1)
If ($Address -eq $BeginAddress) {
BREAK
}
[pscustomobject]@{
WorkSheet = $Worksheet.Name
Column = $Found.Column
Row =$Found.Row
Text = $Found.Text
Address = $Address
}
} Until ($False)
}
Else {
Write-Warning "[$($WorkSheet.Name)] Nothing Found!"
}
}
$workbook.close($false)
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$excel)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()
Remove-Variable excel -ErrorAction SilentlyContinue
}
然后我会用
Get-ChildItem -路径 "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Select-对象-属性目录,名称| ForEach-Object { "{0}{1}" -f $.Directory, $.Name } |搜索-Excel -SearchText MyText
我知道它只能搜索 1 个文件,因为我查看了另一个文件并试图让它发回给我确认,但它不起作用。
如有任何帮助,我们将不胜感激。
您将需要在函数中包含一个循环,或者将函数放在 ForEach-Object
循环中。对于功能更改,您可以执行以下操作:
Function Search-Excel {
[cmdletbinding()]
Param (
[parameter(Mandatory, ValueFromPipeline)]
[ValidateScript({
Try {
If (Test-Path -Path $_) {$True}
Else {Throw "$($_) is not a valid path!"}
}
Catch {
Throw $_
}
})]
[string]$Source,
[parameter(Mandatory)]
[string]$SearchText
#You can specify wildcard characters (*, ?)
)
$Excel = New-Object -ComObject Excel.Application
ForEach($Path in $Source){
### <the rest of your existing code here, adjusted to work with $Path instead of $Source>
}
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$excel)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()
Remove-Variable excel -ErrorAction SilentlyContinue
}
或者,要使用您现有的函数,您可以这样做:
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm |
ForEach-Object { Search-Excel -Source $_.FullName -SearchText MyText }
那么让我们用你的命令来谈谈一些事情。
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Select-Object -Property Directory, Name | ForEach-Object { "{0}{1}" -f $.Directory, $.Name } | Search-Excel -SearchText MyText
如果我们将其分解成单独的部分(用竖线分隔),我们也许能够找出问题所在。第一部分 Get-ChildItem
仅查找匹配 *.xls
、*.xlsx
和 *.xlsm
的文件,因此已经排除了目录。那么,这个函数return到底是做什么的呢?如果您要查看对象类型,您会看到 System.IO.FileInfo
,它内置了一堆属性。其中之一是所需的完整文件路径,.FullName
.
目前,Search-Excel
设置为仅搜索一个文件。如果您想一次搜索多个文件,则需要在某处进行循环。在我看来,最简单的地方就是在函数之外,就像这样:
Get-ChildItem -Path "C:\excelfiles" -Recurse -Include *.xls, *.xlsx, *.xlsm | Foreach-Object { Search-Excel -Source $_.FullName -SearchText MyText }