2011-09-16 16 views
10

Piszę skrypt, który archiwizuje pliki do analizy. Mój problem polega na tym, że nazwy plików nie są unikalne w wielu folderach, więc są nadpisywane.Powershell Uzyskaj folder nadrzędny pliku

Na przykład:

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

Pod koniec mojego procesu kopiowania dostaję tylko 2 pliki, ale chcę 4.

Chciałbym wyjście być tak:

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

Oto mój skrypt do tej pory.

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

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

chcę zrobić coś podobnego copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\

prostu nie jestem pewien, jak to zrobić.

Odpowiedz

13

Jeśli $file jest naprawdę plik - instancją System.IO.FileInfo (a nie naprawdę katalogiem: System.IO.DirectoryInfo) to ma właściwość Directory który jest instancją DirectoryInfo która ma Name:

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

(Używanie potok do uruchomienia, ponieważ parametr -LiteralPath z Copy-Item będzie wiązał się z właściwością PSPath z potoku, więc nie trzeba pobierać nazwy oryginalnego pliku z obiektu $file.)

Jeśli $file może być katalogiem, to trzeba zrobić więcej pracy samemu, ale chyba łatwiej odfiltrować katalogów pierwszy:

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

Uwaga:

  • Nie ma potrzeby, aby zapisać wszystkie obiekty plików, a następnie wykonaj pętlę nad nimi: niech potok wykona pętlę
  • Nie ma potrzeby, aby -i "*.*": jest to zresztą domyślne (i jeśli musisz filtrować pliki według wzorca wieloznacznego, preferuj parametr -filter pattern: filtr jest przekazywany do system plików zamiast kreacji ng. NET obiektów, a następnie filtrowanie ich, które jest znacznie wolniejsze, jeśli istnieje wiele plików).
6

Spróbuj tego:

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

podstawie skryptu, oto inny sposób to zrobić:

$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 
    } 
} 
Powiązane problemy