Home > Mobile >  Powershell substring check
Powershell substring check

Time:05-21

I have this simple script. I just want to match the filename if they contain the substring. However it doesn't work with -like or Contains. What is the right way to do this?

$i = 0
$list1 = @('Gold','Silver')
$list2 = @('W0A-209-193-210_TVIA_Silver_20220520-100001.pdf','W0A-209-195-20_TVIA_Gold_20220520-095934.pdf')
foreach($item in $list2)
    
{
    Write-Host $list1[$i]
    if ($item -like $list1[$i])
    {   
        Write-Host $item   $list1[$i]
        
    }
    $i  
}

Expected Output

W0A-209-193-210_TVIA_Silver_20220520-100001.pdf Silver

W0A-209-195-20_TVIA_Gold_20220520-095934.pdf Gold

Tried this code as well based on this answer but still gives no output

$list1 = @('Gold','Silver')
$list2 = @('W0A-209-193-210_TVIA_Silver_20220520-100001.pdf','W0A-209-195-20_TVIA_Gold_20220520-095934.pdf')
foreach($item in $list2)    
{
    foreach($name in $list1)
        {   
            if ($item -like $name)
                {   
                    Write-Host $item   $name
                }
        
        }
    
}

CodePudding user response:

This is how I would solve it:

$list1 = @('Gold','Silver')
$list2 = @('W0A-209-193-210_TVIA_Silver_20220520-100001.pdf','W0A-209-195-20_TVIA_Gold_20220520-095934.pdf')

foreach( $filename in $list2 ){
    $list1.Where{ $fileName.Contains( $_ ) }.ForEach{ "$fileName $_" }
}

$list1.Where{ $fileName.Contains( $_ ) } filters $list1 based on the given condition (if the current filename contains the substring). $_ refers to the current element of $list1.

.ForEach{ "$fileName $_" } gets called for each filtered element and produces the desired output.

Both .Where and .ForEach are intrinsic methods that are available for all PowerShell objects, but make the most sense when applied to collections (or in general, types that implement IEnumerable).


Another approach is to use regular expression matching. Create a RegEx from $list1 by joining the list items using the RegEx alternation operator |:

$list1 = @('Gold','Silver')
$list1RegEx = $list1 -join '|'

$list2 = @('W0A-209-193-210_TVIA_Silver_20220520-100001.pdf','W0A-209-195-20_TVIA_Gold_20220520-095934.pdf')

foreach( $filename in $list2 ){
    if( $filename -match $list1RegEx ) {
        '{0} {1}' -f $fileName, $matches[0]
    }
}

After a successful match, $matches[0] contains the first matched substring.

As another variation, I'm using the format operator -f to produce the desired outcome.


As for what you have tried:

Your 2nd approach looks most promising. It just has a tiny error in the -like condition. The -like operator doesn't do a substring search, unless you use wildcards:

$list1 = @('Gold','Silver')
$list2 = @('W0A-209-193-210_TVIA_Silver_20220520-100001.pdf','W0A-209-195-20_TVIA_Gold_20220520-095934.pdf')

foreach($item in $list2)    
{
    foreach($name in $list1)
    {   
        if ($item -like "*$name*")
        {   
            Write-Host "$item $name"
        }
    }    
}
  • Related