Показать полную графическую версию : Копирование файла с полной структурой директорий
Uragan66
16-01-2021, 15:57
Доброго времени суток всем!
Никак не получается копирование файла с полной структурой папок. Вроде и не сложный вопрос, но перепробовал и Xcopy, Robocopy и просто Copy-Item, файл копируется без папок.
Собственно, к примеру, есть путь:
C:\papka\papka1\papka2\README.txt
Нужно скопировать файл README.txt на другой раздел, к примеру D, чтобы сохранилась вся структура, включая корневую директорию.
В директории papka2 могут быть и другие файлы и папки, но нужно скопировать только файл README.txt
В итоге на диске D должна получится такая структура:
papka
papka1
papka2
README.txt
Буду премного благодарен за советы и подсказки.
Ну, например, так:
$sSourceFile = 'C:\papka\papka1\papka2\README.txt'
$sDestPath = [System.IO.Path]::Combine('D:', (Split-Path -Path ([System.IO.Path]::GetDirectoryName($sSourceFile)) -NoQualifier))
New-Item -Path $sDestPath -ItemType Directory -Force | Out-Null
Copy-Item -Path $sSourceFile -Destination $sDestPath
param(
$path = "C:\papka\papka1\papka2\README.txt",
$drive = "D"
)cls
Copy $path (NI -F($drive+$path.Remove(0,1)))
Uragan66
16-01-2021, 19:04
Iska, Fors1k, спасибо большое! Оба скрипта работают при копировании в корень диска. А что нужно добавить, чтобы копирование шло в определённую папку, например, J:\RESERV\ttv ?
А что нужно добавить, чтобы копирование шло в определённую папку, например, J:\RESERV\ttv ? »
Uragan66, т.е., из «C:\papka\papka1\papka2\README.txt» получался бы «J:\RESERV\ttv\papka\papka1\papka2\README.txt»?
Попробуйте так (не проверялось):
$sDestPath = [System.IO.Path]::Combine('J:\RESERV\ttv', (Split-Path -Path ([System.IO.Path]::GetDirectoryName($sSourceFile)) -NoQualifier))
В коде коллеги Fors1k тоже просто подставить искомое и чуть изменить код:
$drive = "J:\RESERV\ttv"
…
Copy $path (NI -F($drive+$path.Remove(0,2)))
Uragan66
16-01-2021, 19:39
т.е., из «C:\papka\papka1\papka2\README.txt» получался бы «J:\RESERV\ttv\papka\papka1\papka2\README.txt»? »
да
Попробуйте так (не проверялось): »
так не хочет, копируется в корень диска
По второму коду отлично
Спасибо!
greg zakharov
16-01-2021, 20:21
А позвольте полюбопытствовать для чего необходимо копирование папки на другой раздел? Может просто обойтись созданием символической ссылки?
Uragan66
16-01-2021, 21:10
для чего нужен копирование папки на другой раздел »
если немного подробнее, то копирование нужно перед заменой файлов в плеере SimpleTV. Периодически для него появляются патчи или просто требуется замена его скриптов. Но не всегда патчи удачны и приходится потом всё назад возвращать.
Можно было бы конечно просто бекапы файлов делать, но папка плеера и так немаленькая... Лучше уж их на другой диск скопировать. Ну и структура папок важна, дабы потом не путаться.
greg zakharov
16-01-2021, 22:55
...Но не всегда патчи удачны и приходится потом всё назад возвращать.
Можно было бы конечно просто бекапы файлов делать, но папка плеера и так немаленькая...
Всё равно непонятно для чего нагружать винт ненужным копированием, когда есть SCM. Или у вас SSD? Но и тогда какой смысл "размазывать" данные по накопителю? Берёте какую-нибудь SCM, скажем, git, переходите в корневую папку:
git init
git add -a
git commit -am "контрольная точка с описанием"
А когда понадобится вернуться к одному из ранних состояний, просто делаете откат на нужную контрольную точку. А если еще папка синхронизирована с облаком, то тогда вообще всё шоколадно. Если не хочется заморачиваться с git, можно обойтись fossil - благо один единственный бинарник.
так не хочет, копируется в корень диска »
А… Семён Семёныч… Там и первый код по факту работал некорректно.
Попробуйте так:
$sSourceFile = 'C:\papka\papka1\papka2\README.txt'
$sDestPath = Join-Path -Path 'J:\RESERV\ttv' -ChildPath (Split-Path -Path ([System.IO.Path]::GetDirectoryName($sSourceFile)) -NoQualifier)
New-Item -Path $sDestPath -ItemType Directory -Force | Out-Null
Copy-Item -Path $sSourceFile -Destination $sDestPath
Uragan66
21-01-2021, 12:52
когда понадобится вернуться к одному из ранних состояний, просто делаете откат на нужную контрольную точку »
greg zakharov, спасибо! Совет в копилку, пригодится на будущее... Но в данной задаче с плеером немного не подходит. Пользователи Simple Player часто делятся скриптами и бывает кому-то нужен именно старый скрипт. А их принято выкладывать в полной структуре папок. Да и самому может нужно будет что-то подправить в старом скрипте при его откате.Попробуйте так »
Iska, спасибо большое! Этот код работает, файл копируется в нужную директорию.
Uragan66,
вообще, смотрите в сторону утилиты robocopy, у неё достаточно широкий функционал, в том числе и копирование со структурой...
Но если таки необходимо на powershell:
<#
.SYNOPSIS
Копирование или псевдоперемещение файлов и каталогов с сохранением структуры
.Description
Скрипт предназначен для копирования или перемещения файлов из одного каталога
в другой, при этом сохраняется вложенная структура каталогов. Фактически,
перемещение не выполняется, вместо него работает копирование с последующим
удалением скопированнных итемов.
.Parameter Source
Необязательный: Исходный каталог для выборки элементов. Указывается либо
относительный, либо абсолютный путь.
.Parameter Destination
Необязательный: Целевой каталог. Указывается либо относительный, либо
абсолютный путь.
.Parameter Include
Необязательный: маска(и) для включения файлов в выборку
.Parameter Exclude
Необязательный: маска(и) для исключения файлов из выборки
.Parameter Delete
Переключатель: Если указан, то будут удалены исходные файлы, включенные в выборку,
рекурсивно
.Parameter Emptydelete
Переключатель: Если указан, то будут удалены пустые подкаталоги в исходном каталоге,
рекурсивно
.Example
.\script.ps1 -sourc "D:\FOLDER1" -dest "d:\Folder2" -incl '*.pdf','*.txt' -excl '*_out.*' -del
Это пример перемещения файлов по маскам '*.pdf','*.txt' с исключением из выборки по маске
'*_out.*', с последующим удалением исходных элементов. Пустые каталоги не удаляются.
.Example
.\script.ps1
Это пример копирования/перемещения файлов/каталогов, с сохранением структуры, но
по указанным в самом скрипте параметрам...
.Notes
Created By YuS
Version: 1.00
#>
# requires v 3.0
param (
[string]
$source = ".\Folder1",
[string]
$destination = ".\Folder2",
[string[]]
$include = '*.*',
[string[]]
$exclude = '',
[switch]
$delete,
[switch]
$emptydelete
)
$src = gi -lit $source -force
# копирование файлов с сохранением структуры
dir -lit $src.fullname -inc $include -exc $exclude -rec -force|copy -d {
$d = split-path $_.fullname.replace("$($src.fullname)",$destination)
if (!(test-path -lit $d)){md $d -force} else {$d}
} -force #-whatif
if ($delete) {
# удаляем все скопированные файлы
dir -lit $src.fullname -inc $include -exc $exclude -rec -force -file|
del -force -rec
}
if ($emptydelete) {
# удаляем пустые каталоги
dir -lit $src.fullname -rec -dir -force|sort{$_.fullname.length} -des|%{
if((dir -lit $_.fullname -rec -force) -eq $null){
del -lit $_.fullname -force
}
}
}
greg zakharov
22-01-2021, 12:35
Пользователи Simple Player часто делятся скриптами и бывает кому-то нужен именно старый скрипт. А их принято выкладывать в полной структуре папок.Вы слышали про такую штуку, как виртуальная катологизация?
Uragan66
22-01-2021, 16:49
Но если таки необходимо на powershell »
YuS_2, спасибо! Скрипт хороший. Но для моей задачи не совсем подходит, мне нужно копировать конкретный файл/файлы, не затрагивая при этом другие файлы с таким же расширением, а в Вашем скрипте копирование идёт по маске.
Вы слышали про такую штуку, как виртуальная катологизация? »
честно говоря, только в общих чертах. Но, думаю, это не совсем подойдёт... Если подойдёт мне, то может не подойти другим пользователям плеера. Скрипты то для этого и выкладываются в полной структуре папок, что большинство пользователей не знает куда их ложить, многие и не хотят узнавать, увы... А уж с виртуальной катологизацией то точно никто не захочет разбираться и вникать в это, к сожалению.
копирование идёт по маске. »
полное имя файла с расширением, тоже может быть маской... конечно, если файлов с одинаковыми именами больше одного, то скопированы будут все... это единственная проблемка.
А, да, есть ещё одна "неприятность" - в powershell 5.1, при использовании параметра -literalpath, параметр -include не работает, но его можно заменить на параметр -filter, либо воспользоваться крайней версией powershell, т.е. способ обхода бага есть.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.