PowerShell - Scopri se ci sono due file con lo stesso nome
-
21-12-2019 - |
Domanda
Sto cercando di controllare una serie di directory e sottodirectory per vedere se ci sono due o più file con lo stesso nome nella stessa cartella.Penso che il mio problema sia come sto cercando di convalidare una stringa.
Per la seguente directory di test:
- .
- | - C: \ Test \
- .
- | --c: \ Test \ yy \
- .
- | --c: \ Test \ yy \ xx.log
- | --c: \ Test \ yy \ xx.txt
- | --c: \ Test \ yy \
- | - C: \ Test \ zz \
- | - C: \ Test \ zz.log
- | - C: \ Test \ zz.txt
Ho bisogno del mio codice per trovare xx.log e zz.log.Posso includere un controllo contro $_.PSisContainer
(ma non pensavo che fosse necessario).
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"
fornisce la stringa giusta ma non posso utilizzare quella stringa per convalidare l'esistenza del file.
Qualcuno può aiutare a correggere il mio codice?Mi piacerebbe imparare come gestire stringhe concatenate come questa - è un trucco che penso sarebbe utile in altre aree.
Soluzione
Questo non è inteso come risposta, piuttosto un commento, ma quindi non mi permette di aggiungere commenti in questo momento: (
R_C_III - Immagino che ci siano due errori nel codice originale.
Prima di tutto, non crea il percorso completo del file (I.e. DirectoryName + Basename + .txt). Piuttosto che concatenare le corde per farlo, Keith ha utilizzato la capacità di Powershell di eseguire sostituzioni di valore all'interno delle corde a doppia citata. ad esempio.
$s = "there"
write-host "hello $s"
.
Risultati in
hello there
.
Per inserire le proprietà dell'oggetto in una stringa in questo modo è necessario utilizzare le sub-espressioni come spiega Keith.
$file = get-item "c:\somefile.txt"
write-host "$($file.DirectoryName)\$($file.BaseName).NEW"
.
Risultati in
c:\somefile.NEW
.
In secondo luogo (secondo il mio commento sulla risposta di Keith), il codice originale non controlla l'esistenza della versione ".txt" del file. La seconda clausola nell'istruzione IF tenta di equiparare il nome file modificato con $ true ($ elemento.basename + ". Txt" -eq $ true). Questa clausola valuterà sempre come false.
La modifica di Keith aggiunge il cmdlet 'Test-Path' che, in questa istanza, controlla l'esistenza del file '.txt'.
Altri suggerimenti
Prova questo:
gci C:\Test -recurse -file | Where {$_.extension -ne ".txt" -AND (Test-Path "$($_.DirectoryName)\$($_.BaseName).txt")}
.
Non è necessario l'istruzione iniziale Foreach
come comandi PowerShell che i dati di uscita possono essere utilizzati direttamente all'inizio di una pipeline.Quindi filtri oggetti conduttura con il comando Where
.