Powershell Получить родительскую папку файла
Я пишу script, который архивирует файлы для анализа. Моя проблема в том, что имена файлов не уникальны по нескольким папкам, поэтому они переписываются.
Например:
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
Здесь мой script.
$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\
Я просто не уверен, как это сделать.
Ответы
Ответ 1
Если $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, а затем фильтрует они намного медленнее, если файлов много).
Ответ 2
Попробуйте следующее:
dir -r -path C:\StuffToCopy |
where {!$_.psiscontainer} |
copy -dest { "C:\ArchiveCopy\$($_.Directory.Name)_$($_.Name)"}
Ответ 3
Основываясь на вашем script, вот еще один способ сделать это:
$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
}
}