Question

I'm trying to check a series of directories and subdirectories to see if there are two or more files with the same name in the same folder. I think my issue is how I'm trying to validate a string.

For the following test directory:

  • |-- C:\Test\
    • |--C:\Test\YY\
      • |--C:\Test\YY\xx.log
      • |--C:\Test\YY\xx.txt
    • |-- C:\Test\ZZ\
    • |-- C:\Test\ZZ.log
    • |-- C:\Test\ZZ.txt

I need my code to find xx.log and ZZ.log. I can include a check against $_.PSisContainer (but I didn't think it was necessary).

ForEach ($item in (gci "C:\Test\*" -recurse)) {
    If ($item.extension -notmatch "txt" -AND $item.basename+".txt" -eq $True) {
        Write-Host $item.fullname
        } 
    }

$item.basename+".txt" provides the right string but I can't use that string to validate the existence of the file.

Can anyone help correct my code? I'd like to learn how to handle concatenated strings like this--it's a trick I think would be useful in other areas.

Was it helpful?

Solution

This not intended as an answer, rather a comment, but SO is not allowing me to add comments right now :(

R_C_III - I guess there are two errors in the original code.

Firstly, it does not build the complete file path (i.e. DirectoryName + BaseName + .TXT). Rather than concatenate strings to do this, Keith has used PowerShell's ability to perform value substitutions inside double-quoted strings. e.g.

$s = "there"
write-host "hello $s"

results in

hello there

To insert object properties into a string in this way it's necessary to use sub-expressions as Keith explains.

$file = get-item "c:\somefile.txt"
write-host "$($file.DirectoryName)\$($file.BaseName).NEW"

results in

c:\somefile.NEW

Secondly (as per my comment on Keith's answer), the original code does not check for the existence of the '.txt' version of the file. The second clause in the IF statement attempts to equate the modified filename with $True ($item.basename+".txt" -eq $True). This clause will always evaluate as false.

Keith's modification adds the 'Test-Path' CmdLet which, in this instance, checks for the existence of the '.txt' file.

OTHER TIPS

Try this:

gci C:\Test -recurse -file | Where {$_.extension -ne ".txt" -AND (Test-Path "$($_.DirectoryName)\$($_.BaseName).txt")}

You don't need the initial Foreach statement as PowerShell commands that output data can be used directly at the start of a pipeline. Then you filter pipeline objects with the Where command.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top