Powershell Получить родительскую папку файла - PullRequest
12 голосов
/ 16 сентября 2011

Я пишу скрипт, который архивирует файлы для анализа.Моя проблема в том, что имена файлов не являются уникальными для нескольких папок, поэтому они перезаписываются.

Например:

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\

Я просто не знаю, как это сделать.

Ответы [ 3 ]

13 голосов
/ 16 сентября 2011

Если $file действительно файл - экземпляр System.IO.FileInfo (а не каталог: System.IO.DirectoryInfo), то у него есть свойство Directory, которое является экземпляром DirectoryInfo с Name:

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

(Использование конвейера для запуска, поскольку параметр -LiteralPath Copy-Item будет привязан к свойству 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: фильтр передается файловой системе, а не создает объекты .NET, а затем фильтрует их, что намного медленнее, если файлов много).
6 голосов
/ 16 сентября 2011

Попробуйте это:

dir -r -path C:\StuffToCopy | 
        where {!$_.psiscontainer} | 
        copy -dest { "C:\ArchiveCopy\$($_.Directory.Name)_$($_.Name)"}
5 голосов
/ 16 сентября 2011

На основе вашего сценария, вот еще один способ сделать это:

$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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...