2011-09-16 231 views
10

我正在编写一个脚本,用于分析文件。我的问题是文件名在多个文件夹中不唯一,因此它们被覆盖。Powershell获取文件的父文件夹

例如:

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

在我的复制过程,我只得到2个文件的末尾,但我想4

我想输出是这样的:

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

这是我的脚本到目前为止。

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

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

我要像做copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\

我只是不知道如何做到这一点。

回答

13

如果$file确实是一个文件 - 的System.IO.FileInfo一个实例(而不是一个真正的目录:System.IO.DirectoryInfo),那么它具有财产Directory这是具有NameDirectoryInfo一个实例:

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

(使用因为Copy-Item-LiteralPath参数将绑定到管道中的PSPath属性,所以不需要从$file对象中抽取原始文件的名称。)

如果$file可能是一个目录,那么你需要做更多的工作自己,但可能更容易先筛选出目录:

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

注:

  • 没有必要保存所有的文件对象然后遍历它们:让流水线循环播放
  • 无需-i "*.*":无论如何这是默认设置(如果需要在通配符模式中过滤文件,请选择-filter pattern参数:将过滤器传递给文件系统而不是creati然后过滤它们,如果有很多文件,它们会慢得多)。
6

试试这个:

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

根据你的脚本,这里是另一种方式来做到这一点:

$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 
    } 
} 
相关问题