Reputation: 23
I’m wondering how to take a list of partial document names and return a list of the full document names with PowerShell.
I have ton of documents to do this with. We have a naming scheme: HG-xx-xx-###
The full naming scheme for the actual files is: HG-xx-xx-###.x.x_File_Name
I have a lot of different lists of file names like so:
HG-SP-HG-001
HG-WI-BE-005
HG-GD-BB-043
I'm trying to have program return a list of the full file names like so:
HG-SP-HG-001.1.6_Example
HG-WI-BE-005.1.0_Example
HG-GD-BB-043.1.1_Example
I've included both methods I've tried. I give it a list or even just one partial file name and I get nothing back.
I've tried two different ways and I'm at the end of my programming and googling capabilities, any ideas?
$myPath = 'P:\'
$_DocList = READ-HOST "Enter list of document ID's"
$_DocList = $_DocList.Split(',').Split(' ')
#Here I'm not sure if I should do it like so:
$output =
ForEach($_Doc in $_DocList)
{
$find = gci $myPath -Recurse |where{$_.name -contains $($_Doc)}
Write-Host "$find"
}
$output | clip
#or like this:
$_DocList | ForEach-Object
{
gci -Path $myPath -Filter $_ -Recurse
$info = Get-ChildItem $_.FullName | Measure-Object
if ($info.Count -ne 0) {
Write-Output "$($_.Name)"
}
} | clip
Upvotes: 2
Views: 1262
Reputation: 801
If you have an established pattern of what the files look like, why not regex it?
# Use these instead to specify a docID
#$docID = "005"
#pattern = "^HG(-\w{2}){2}-$docID"
$pattern = "^HG(-\w{2}){2}-\d{3}"
Get-ChildItem -Path "P:\" -Recurse | ?{$_ -match $pattern}
Granted, there may be more efficient ways to do this, but it should be quick enough for a few thousand files.
EDIT: This is the breakdown of the regex pattern's hieroglyphics.
^
Start at the beginning
HG
literal characters "HG"
(-\w{2})
(
start of a grouping
-
literal "-" character (hyphen)
\w{2}
\w
any word character{2}
exactly 2 times)
End of the grouping
{2}
exactly 2 times
-
literal "-" character (hyphen)
\d
any digit 0 through 9
{3}
Exactly 3 times
Upvotes: 1
Reputation: 437988
Doug Maurer's helpful answer shows a solution based on a wildcard pattern based to the -Filter
parameter.
Since this parameter only accepts a single pattern, the Get-ChildItem -Recurse
call must be called multiple times, in a loop.
However, since you're using -Recurse
, you can take advantage of the -Include
parameter, which accepts multiple patterns, so you can get away with one Get-ChildItem
call.
While for a single Get-ChildItem
call -Filter
performs better than -Include
, a single Get-ChildItem -Include
call with an array of pattern is likely to outperform multiple Get-ChildItem -Filter
calls, especially with many patterns.
# Sample name prefixes to search for.
$namePrefixes = 'HG-SP-HG-001', 'HG-WI-BE-005', 'HG-GD-BB-043'
# Append '*' to all prefixes to form wildcard patterns: 'HG-SP-HG-001*', ...
$namePatterns = $namePrefixes -replace '$', '*'
# Combine Get-ChildItem -Recurse with -Include and all patterns.
# .Name returns the file name part of all matching files.
$names = (Get-ChildItem $myPath -File -Recurse -Include $namePatterns).Name
Upvotes: 2
Reputation: 8868
When using the filter with partial names you'll need to specify wildcard
$names = 'HG-SP-HG','HG-WI-BE','HG-GD-BB'
$names | Foreach-Object {
Get-ChildItem -File -Filter $_* -Recurse
}
And if you only want the full path back, simply select it.
$names = 'HG-SP-HG','HG-WI-BE','HG-GD-BB'
$names | Foreach-Object {
Get-ChildItem -File -Filter $_* -Recurse
} | Select-Object -ExpandProperty FullName
Upvotes: 1
Reputation: 607
Maybe something like this?
$docList = @('HG-SP-HG','HG-WI-BE','HG-GD-BB')
$docList | Get-ChildItem -File -Filter $_ -Recurse | select Name
Upvotes: 1
Reputation: 189
Maybe something like this?
$docList = @('HG-SP-HG-*','HG-WI-BE-*','HG-GD-BB-*')
foreach($item in $docList)
{
$check = Get-ChildItem -Filter $item P:\ -File
if($check)
{
$check
}
}
Upvotes: 1