2011-09-16 40 views
10

Tôi đang viết một tập lệnh lưu trữ tệp để phân tích. Vấn đề của tôi là các tên tệp không phải là duy nhất trên nhiều thư mục để chúng bị ghi đè.Powershell Nhận thư mục gốc của một tệp

Ví dụ:

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

Vào cuối quá trình sao chép của tôi tôi chỉ nhận được 2 file, nhưng tôi muốn 4.

Tôi muốn đầu ra được như thế này:

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

Đây là tập lệnh của tôi cho đến thời điểm này.

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

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

tôi muốn làm một cái gì đó giống như copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\

Tôi chỉ không chắc chắn làm thế nào để làm điều đó.

Trả lời

13

Nếu $file thực sự là một tập tin - một thể hiện của System.IO.FileInfo (và không phải thực sự là một thư mục: System.IO.DirectoryInfo) sau đó nó có tài sản Directory mà là một thể hiện của DirectoryInfo trong đó có một Name:

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

(Sử dụng một đường ống để bắt đầu vì thông số -LiteralPath của Copy-Item sẽ liên kết với thuộc tính PSPath từ đường ống, vì vậy không cần phải kéo tên của tệp gốc từ đối tượng $file.)

Nếu $file có thể là một thư mục, sau đó bạn cần phải làm nhiều hơn công việc cho mình, nhưng có lẽ dễ dàng hơn để lọc ra các thư mục đầu tiên:

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

Lưu ý:

  • Không cần phải lưu tất cả các đối tượng tệp và sau đó lặp lại chúng: hãy để đường ống làm vòng lặp
  • Không cần phải -i "*.*": đây là mặc định (và nếu bạn cần lọc tệp trên mẫu ký tự đại diện, hãy tham số -filter pattern: bộ lọc được chuyển đến hệ thống tập tin hơn là tạo Đối tượng .NET và sau đó lọc chúng chậm hơn nhiều nếu có nhiều tệp).
6

Hãy thử điều này:

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

Dựa trên kịch bản của bạn, đây là một cách khác để làm điều này:

$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 
    } 
} 
Các vấn đề liên quan