pevin
pevin

Reputation: 23

How to take a list of partial file names and return a list of the full file names with PowerShell

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

Answers (5)

PowerShellGuy
PowerShellGuy

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

mklement0
mklement0

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

Doug Maurer
Doug Maurer

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

DEV-Jacol
DEV-Jacol

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

dno
dno

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

Related Questions