Home > Mobile >  Powershell find string that matches multiple criteria from an arraylist
Powershell find string that matches multiple criteria from an arraylist

Time:02-03

Fairly new to PowerShell and am looking to figure out how to find a name of a directory that matches multiple criteria from an array list.

The below code is what has been developed so far:

    $InputAddress = Read-Host -Prompt 'Enter in a job address'
    # Remove any non alphanumeric characters and white spaces
    $InputAddress = ($InputAddress -replace '[^a-zA-Z\d\s]') 
    # Remove any double spaces and split to separate into an array
    $InputAddress = [System.Collections.ArrayList]($InputAddress -replace '  ',' ').split(" ")
    while ($InputAddress -contains "USA")
    {
        $InputAddress.Remove("USA")
    }

    $srcRoot = (Get-ChildItem -Path 'C:\Users\' -Filter "Box" -Recurse -Directory -Depth 1 -ErrorAction:Ignore).Fullname '\'
    $JobRoot = (Get-ChildItem -Path $srcRoot -Filter "*Backup*" -Recurse -Directory -Depth 0).Fullname

    $JobFolder = (Get-ChildItem -Path $JobRoot -Filter "$InputAddress" -Recurse -Directory -Depth 0)
    Write-Output $JobFolder

The address that is inputted from Read-Host is "1234 street - cityname, CA USA", which when it goes through the script creates an array list of:

1234
street
cityname
CA

The intended folder that would need to be found is named "1234 street, cityname, CA - ABC Company"

Some background info is PowerShell 5.1 is being used, Windows 10 OS.

Could someone help me understand how to include all criteria when performing the Get-ChildItem? My current best guess is that either wildcards * are needed, or -and type to include all items.

Edit: Some more background regarding the folder structure of all the folders that are named as addresses-is that all folders start with the number, then the street name, then sometimes the state/province. If the street number narrows down the amount of folders, and then the street name narrows it down to one folder, this would be ideal. Basically each ordered element could narrow the search further until only one folder is returned.

CodePudding user response:

Assuming $JobFolder is the array containing all the folders and $InputAddress is the collection of all of elements we want to compare against each folder, this is the logic I would use:

foreach($dir in $JobFolder) {
    $skip = foreach($word in $InputAddress) {
        if($dir.Name -notmatch $word) {
            $true
            break
        }
    }
    if(-not $skip) { $dir }
}
  1. Outer Loop: Enumerate the Directories.
  2. Inner Loop: Enumerate the words we need to match.
  3. Inner Condition: If the Name of the Folder does not match with any of the words we need to match, break the inner loop and return $true.
  4. Outer Condition: If the returned value from the inner loop negated is $true (in other words, if the inner loop returned $null, which when negated is $true), return the DirectoryInfo object, else, go to the next iteration.

As you can tell, this code will only work with a 100% match of the elements on $InputAddress.

Note, this is doing the comparison against the folder's Name, if you need to do the comparison against against all the parent folders you would use $dir.FullName instead of $dir.Name.

CodePudding user response:

Wouldn't structuring your data be simpler?

It seems to me that the only use case for this data is to store addresses, find/retrieve addresses, and maybe find addresses that are near each other. In these cases, a folder structure similar to

D:\Addresses\{States}\{Cities|zips}\{Streets}\{Files representing each address}

would seem to be reasonable solution.

So, if your data is in CSV files, and using the example address, its file's path would be

D:\Addresses\CA\cityname\street\1234.CA.cityname.street.csv

NOTE: The final file will still have the full address, that way if somehow it gets moved, you don't have to struggle to figure out where it came from. And placing the number part at the front of the file's name will probably make it easier to find both visually and by code.

  •  Tags:  
  • Related