2011-09-16 16 views
10

Sto scrivendo uno script che archivia i file per l'analisi. Il mio problema è che i nomi dei file non sono univoci su più cartelle quindi vengono sovrascritti.PowerShell Ottieni cartella principale di un file

Per esempio:

C:\StuffToCopy\Folder1\myFile1.txt 
C:\StuffToCopy\Folder1\myFile2.txt 
C:\StuffToCopy\Folder2\myFile1.txt 
C:\StuffToCopy\Folder2\myFile2.txt 

Alla fine del mio processo di copia che sto ottenendo soltanto 2 file, ma voglio 4.

mi piacerebbe l'uscita per essere come questo:

C:\ArchiveCopy\Folder1_myFile1.txt 
C:\ArchiveCopy\Folder1_myFile2.txt 
C:\ArchiveCopy\Folder2_myFile1.txt 
C:\ArchiveCopy\Folder2_myFile2.txt 

Ecco il mio script finora.

$files = dir -r -path "C:\StuffToCopy\" -i *.* 

foreach ($file in $files) 
{ 
    if ($file.LastWriteTime -gt (get-date).AddDays(-1)) { 
     copy -path $file C:\ArchiveCopy\ 
    } 
} 

voglio fare qualcosa di simile copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\

Solo che non sono sicuro di come farlo.

risposta

13

Se $file è davvero un file - un esempio di System.IO.FileInfo (e non realmente una directory: System.IO.DirectoryInfo) allora ha proprietà Directory che è un'istanza di DirectoryInfo che ha un Name:

$file | 
    copy-item -destination { 
    Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) } 

(Utilizzo di un conduttura per avviare perché il parametro di -LiteralPathCopy-Item si legherà alla proprietà PSPath dalla tubazione, quindi nessun bisogno di tirare il nome del file originale dall'oggetto $file.)

Se $file potrebbe essere una directory, allora avete bisogno di fare di più il lavoro da soli, ma probabilmente più facile per filtrare le directory prima:

dir -r -path C:\StuffToCopy\ | 
    where { -not $_.PSIsContainer } | 
    copy-item -destination { 
    Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) } 

Nota:

  • Non c'è bisogno di salvare tutti i file object e quindi loop su di essi: lascia che la pipeline esegua il loop
  • Non c'è bisogno di -i "*.*": questo è comunque l'impostazione predefinita (e se è necessario filtrare i file su un carattere jolly preferisci il parametro -filter pattern: il filtro viene passato al filesystem piuttosto che creati ng. Oggetti .NET e quindi filtrarli, che è molto più lento se ci sono molti file).
6

Prova questo:

dir -r -path C:\StuffToCopy | 
     where {!$_.psiscontainer} | 
     copy -dest { "C:\ArchiveCopy\$($_.Directory.Name)_$($_.Name)"} 
3

Sulla base della sua sceneggiatura, ecco un altro modo per farlo:

$files = dir -r -path "C:\StuffToCopy\" -i *.* 
$destPath = "c:\ArchiveCopy\" 

foreach ($file in $files) 
{ 

    $folderPath = Split-Path $file.fullname -parent 
    $folder = Split-Path $folderPath -leaf 
    $destFilename = $folder + "_" + $file.name 
    $destFileFullPath = $destPath + $destFilename 
    write-host $destFileFullPath 
    if ($file.LastWriteTime -eq (get-date).AddDays(0)) { 
     copy -path $file $destFileFullPath 
    } 
} 
Problemi correlati