How do I find a file when only part of the file name is known using Powershell?

64 views Asked by At

For certain types of files there maybe a pdf equivalent. However this pdf file may have characters added to the left, right or may be exactly the same. For example for file TAX457.idw, there maybe TAX457-1.pdf or just TAX457.pdf

I also need the file name of this pdf file. $filePdf variable just doesn't work. I have tried ".*$([regex]::Escape($baseName)).*\.pdf" this just doesn't work. The output is as if there is no file in the folder. "*$($baseName)*.pdf" this returns files that are not pdf for but adds .pdf and * to the file name. For example there are three files in folder B26945.idw,B26945.ipt, and B2694501.pdf the output is \\EngDesignLib\026\026945.007\*B26945*.pdf \\nml-fp\EngDesignLib\026\026945.007\*B26945*.pdf

The intended output is \\EngDesignLib\026\026945.007\B26945.idw \\EngDesignLib\026\026945.007\B26945.ipt \\EngDesignLib\026\026945.007\B2694501.pdf

EDIT: Some more information:

  1. '026' and '026945.007' in the path comes from SQL. I construct these paths based on information in SQL and then look for files
  2. I only want pdf of the extension mentioned in the $fileExtnesion variable
  3. Not all of the files will have a pdf equivalent.
$fileExtensions = @("*.ipt", "*.iam", "*.ipn", "*.idw")
Get-ChildItem -Path $PathEngDesign -File -Include $fileExtensions -Recurse -ErrorAction SilentlyContinue -Force|ForEach-Object{
$file = $_
$baseName = $file.Basename
                $filename = $file.Name
                $filePdf = "*$($baseName)*.pdf"
 $pdfFilePath = $file.fullname -Replace ($filename, $filePdf)
Write-host "Path" $file.FullName
  If (Test-Path $pdfFilePath){
                    Write-host "PDF File and Path Found" $filePdf "PATH-->" $pdfFilePath
}
}`
3

There are 3 answers

0
mclayton On BEST ANSWER

Your Test-Path $pdfFilePath (where $pdfFilePath equals, e.g. \\nml-fp\EngDesignLib\026\026945.007\*B26945*.pdf) answers the question:

does a file exist that matches this pattern?

But it sounds like the question you really want to ask is:

what is the name of the file that matches this pattern?

To answer that you can replace your If (Test-Path $pdfFilePath) { ... } with this:

    $pdf = Get-ChildItem -Path $pdfFilePath
    if( $null -ne $pdf )
    {
        Write-host "PDF File and Path Found" $filePdf "PATH-->" $pdf.FullName
    }

Note - there might be more than one match, but the code above assumes there's only one at most. If you have multiple matches you'll need to handle that differently...

If I run that on my machine I get this output instead:

Path C:\src\so\test\B26945.idw
PDF File and Path Found *B26945*.pdf PATH--> C:\src\so\test\B2694501.pdf

where the name of the file is shown rather than the search pattern.

0
sirtao On

-Filter already does what you need, no reason to use -Include

# Set the known part of the name
$KnownPart = 'TAX45'

# Recursively get all files having that part in their name, with anything before or after
Get-ChildItem -Path $PathEngDesign -Filter *$KnownPart* -Recurse -ErrorAction SilentlyContinue -Force | 
    ForEach-Object { 
        # Tests if there is a Item that has the same name but with PDF as extension. This includes the PDF files themselves, so you get all.
        if (Test-Path -PathType Leaf ( Join-Path -Path $_.DirectoryName -ChildPath "$($_.basename).pdf"  )) {
            # prints the full name. Or whatever you want.
            $_.FullName
        } 
    }
0
Theo On

I would first filter to get just the *.idw and *.ipt files, then group these on their basename and in a loop try and find one (or more) matching pdf file(s).

If that succeeds, output the resulting FullNames

$PathEngDesign  = '\\EngDesignLib\026\026945.007'
$fileExtensions = '*.idw', '*.ipt'   # leave out '*.pdf'

(Get-ChildItem -Path $PathEngDesign -File -Include $fileExtensions -Recurse -Force -ErrorAction SilentlyContinue) |
Group-Object BaseName |
ForEach-Object {
    # create a filter path with wildcards for the matching pdf you need to find
    $pdfPath = Join-Path -Path $PathEngDesign -ChildPath ('*{0}*.pdf' -f $_.Name) # the Group name is the file BaseName
    $pdfFile = @(Get-Item -Path $pdfPath -Force -ErrorAction SilentlyContinue)    # there may be zero, one or more..
    if ($pdfFile.Count) {
        # output the file fullnames
        Write-Host ($_.Group.FullName -join [environment]::NewLine)  # first the idw and ipt files
        Write-Host ($pdfFile.FullName -join [environment]::NewLine)  # then the matching pdf file(s)
    }
}