Лучший отвечающий
Posh: скопировать файлы, в исходном месте оставить только мастер файл и последних четыре файла, всё остальное удалить

Вопрос
-
Поделюсь, вдруг кому надо будет:
Изначальная задача выглядела так:
Archive.bak созданный при царе горохе
И к нему каждую неделю добавляется инкремент
Archive1.bak, Archive2.bak ... ArchiveN.bak
Как бы так собирать батником каждый раз только инкременты, копировать их в надежное место и дропать оставляя мастер файл в родном каталоге, вместе с четырьмя последними инкрементами.
http://community.livejournal.com/ru_sysadmins/1232149.html
код:
$files = get-childitem | sort lastwritetime $filesLastFour = $files | select -last 4 $masterFile = Get-ChildItem "bla.xml" $destination = "d:\temp\" if ((test-path ($destination + $masterfile.name )) -eq $false) { # copy $masterfile.name $destination write-host copy $masterfile.name $destination } Foreach ($file in $files) { if ($masterfile.Name -eq $file.Name) {continue} # copy $file $destination write-host copied $file to $destination } Foreach ($file in $files) { if ($filesLastFour -contains $file) {continue} if ($masterfile.Name -eq $file.Name) {continue} # del $file write-host del $file } write-host ==== last four $filesLastFour | select name write-host ==== master $masterFile | select name</em>
Как сделать так, чтобы не копировались файлы которые уже есть в месте назначения - на домашнее задание =)
MSBF21 октября 2009 г. 9:42
Ответы
-
> Как бы так собирать батником каждый раз только инкременты, копировать их в надежное место и дропать оставляя мастер файл в родном каталоге, вместе с четырьмя последними инкрементами.
Из test в test2
@echo off
setlocal
for %%i in ("test\archive*.bak") do set /a cnt+=1
set /a cnt-=5
for /l %%i in (%cnt%,-1,1) do (
if not exist "test2\archive%%i.bak" (move "test\archive%%i.bak" "test2") else (del "test\archive%%i.bak" )
)
- Помечено в качестве ответа panda_fs2 24 октября 2009 г. 10:59
21 октября 2009 г. 10:38 -
01MDM из условия не следует что мастер файл постоянно меняется, скорее наоборот.
t1 - исходная папка, t2 - назначения. Если в t2 уже присутствуют какие то файлы, они не будут перезаписаны.
ls t1 -Exclude arc.bak | sort lastwritetime | select -First ((ls t1).count -5) | mv -Destination t2 -ea 0
AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com- Помечено в качестве ответа panda_fs2 22 октября 2009 г. 11:32
21 октября 2009 г. 15:32Модератор -
> Я не про юникод, слава богу, я про то что файлы могут называться как угодно, хоть archiv_pervii.bak, archiv_vtoroii.bak и т.п.
Так это реализуется проще некуда:
@echo off for /f "skip=4 tokens=*" %%i in ('dir /b /od test\*.bak ^| findstr /v archiv.bak') do ( echo executing if condition with "%%i" )
Просто первоначальное условие можно понять двояко. По ссылке: "Archive1.bak, Archive2.bak ... ArchiveN.bak"
А это не дочитал: "Понимаю, что надо как то отталкиваться от даты создания файла."- Помечено в качестве ответа panda_fs2 24 октября 2009 г. 10:59
23 октября 2009 г. 21:09
Все ответы
-
Как сделать так, чтобы не копировались файлы которые уже есть в месте назначения - на домашнее задание =)
домашнее задание простенькое :P
If (test-path $destination + $file.name){Break}
Если ответ Вам помог, нажмите на изображение зеленой галочки - «пометить как ответ». Так же, Вы можете пометить это сообщение как «полезное», нажав на ссылку "проголосовать за полезное сообщение".21 октября 2009 г. 9:52 -
> Как бы так собирать батником каждый раз только инкременты, копировать их в надежное место и дропать оставляя мастер файл в родном каталоге, вместе с четырьмя последними инкрементами.
Из test в test2
@echo off
setlocal
for %%i in ("test\archive*.bak") do set /a cnt+=1
set /a cnt-=5
for /l %%i in (%cnt%,-1,1) do (
if not exist "test2\archive%%i.bak" (move "test\archive%%i.bak" "test2") else (del "test\archive%%i.bak" )
)
- Помечено в качестве ответа panda_fs2 24 октября 2009 г. 10:59
21 октября 2009 г. 10:38 -
01MDM из условия не следует что мастер файл постоянно меняется, скорее наоборот.
t1 - исходная папка, t2 - назначения. Если в t2 уже присутствуют какие то файлы, они не будут перезаписаны.
ls t1 -Exclude arc.bak | sort lastwritetime | select -First ((ls t1).count -5) | mv -Destination t2 -ea 0
AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com- Помечено в качестве ответа panda_fs2 22 октября 2009 г. 11:32
21 октября 2009 г. 15:32Модератор -
01MDM из условия не следует что мастер файл постоянно меняется, скорее наоборот.
t1 - исходная папка, t2 - назначения. Если в t2 уже присутствуют какие то файлы, они не будут перезаписаны.
ls t1 -Exclude arc.bak | sort lastwritetime | select -First ((ls t1).count -5) | mv -Destination t2 -ea 0
AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com
Вы меня сделали =)
MSBF22 октября 2009 г. 11:32 -
> 01MDM из условия не следует что мастер файл постоянно меняется, скорее наоборот.
Так у меня он и не меняется. Archiv.bak всегда остается на месте. Другое дело, что я сразу не понял, что нужен не батник. А в остальном, если файлы с инкрементами идут по порядку, то и батник отрабатывает правильно.
Но и `select lastwritetime` не гарантирует правильное решение. Файл может быть создан или изменен позже, а порядковый номер иметь меньший. Например после выполнения остаются archiv.bak, archiv6.bak-archiv9.bak. При следующем заполнении каталога более свежие файлы будут иметь меньший порядковый номер от 1 до 5.23 октября 2009 г. 9:17 -
> 01MDM из условия не следует что мастер файл постоянно меняется, скорее наоборот.
Так у меня он и не меняется. Archiv.bak всегда остается на месте. Другое дело, что я сразу не понял, что нужен не батник. А в остальном, если файлы с инкрементами идут по порядку, то и батник отрабатывает правильно.
Но и `select lastwritetime` не гарантирует правильное решение. Файл может быть создан или изменен позже, а порядковый номер иметь меньший. Например после выполнения остаются archiv.bak, archiv6.bak-archiv9.bak. При следующем заполнении каталога более свежие файлы будут иметь меньший порядковый номер от 1 до 5.
В оригинале человек хотел именно батник, но ему дали решение на ПШ, как более результативное.
а по поводу второго пункта - так время модификации файла всё-равно будет более позднее чем у других, это раз;
во вторых никто не говорил что новые инкременты будут начинать нумерацию снова с единицы.
ну и в третих решение на ПШ позволяет работать с абсолютно любыми названиями файлов.
MSBF23 октября 2009 г. 14:28 -
Я с вами не спорю. Но:
> а по поводу второго пункта - так время модификации файла всё-равно будет более позднее чем у других
Да, но если к более ранним не было доступа.
Я вопрос понял так, что файлы должны перемещаться/удаляться в зависимости от значения цифрового индекса: "вместе с четырьмя последними инкрементами "
Если бы критерием служило время модификации или создания, то тогда бы сортировка шла исходя из этого. Это тоже просто.
> никто не говорил что новые инкременты будут начинать нумерацию снова с единицы.
Тогда теряется сам смысл нумерации файлов. Значит оставшиеся четыре надо переименовывать (Archiv(1..4).bak)
> решение на ПШ позволяет работать с абсолютно любыми названиями файлов.
Cmd тоже работает в юникодном режиме (cmd /u), тоже utf16, и тоже с любыми названиями. Через переменную %cmdcmdline% можно определить режим и перезапустить батник в юникоде. Или сразу запускать cmd /u arch.cmd23 октября 2009 г. 15:07 -
Я с вами не спорю. Но:
> а по поводу второго пункта - так время модификации файла всё-равно будет более позднее чем у других
Да, но если к более ранним не было доступа.
Я вопрос понял так, что файлы должны перемещаться/удаляться в зависимости от значения цифрового индекса: "вместе с четырьмя последними инкрементами "
Если бы критерием служило время модификации или создания, то тогда бы сортировка шла исходя из этого. Это тоже просто.
> никто не говорил что новые инкременты будут начинать нумерацию снова с единицы.
Тогда теряется сам смысл нумерации файлов. Значит оставшиеся четыре надо переименовывать (Archiv(1..4).bak)
> решение на ПШ позволяет работать с абсолютно любыми названиями файлов.
Cmd тоже работает в юникодном режиме (cmd /u), тоже utf16, и тоже с любыми названиями. Через переменную %cmdcmdline% можно определить режим и перезапустить батник в юникоде. Или сразу запускать cmd /u arch.cmd
И я с Вами тоже, просто объясняю исходные условия.
Мне кажется что дата модификации более часто встречающийся критерий, чем нумерация.
Нет, не теряется, ибо как-то надо отличать мастер файл и инкременты, и это не обязательно просто увеличение номера на едницу (мы ведь кстати не знаем системы нумерации ;)), а может быть и дата, и причем не обязательно в виде YYYYMMDDHHmm, а в более сложных вариантах (например человеко-читаемый YYYY-MM-DD_HH-mm, который cmd маловероятно что осилит). А с переименованием Вы что-то загнули, ибо если у нас файлы будут переименовываться (опять-таки зачем?!) то при попытке перемещения их в архив они затрут копии предыдущей итерации (которые тоже были 1..4.bak).
Я не про юникод, слава богу, я про то что файлы могут называться как угодно, хоть archiv_pervii.bak, archiv_vtoroii.bak и т.п.
MSBF23 октября 2009 г. 19:00 -
> Я не про юникод, слава богу, я про то что файлы могут называться как угодно, хоть archiv_pervii.bak, archiv_vtoroii.bak и т.п.
Так это реализуется проще некуда:
@echo off for /f "skip=4 tokens=*" %%i in ('dir /b /od test\*.bak ^| findstr /v archiv.bak') do ( echo executing if condition with "%%i" )
Просто первоначальное условие можно понять двояко. По ссылке: "Archive1.bak, Archive2.bak ... ArchiveN.bak"
А это не дочитал: "Понимаю, что надо как то отталкиваться от даты создания файла."- Помечено в качестве ответа panda_fs2 24 октября 2009 г. 10:59
23 октября 2009 г. 21:09 -
В общем ладно, кому надо копировать инкрементые архивы - имеют аж четыре варианта действий =)
Всем спасибо.
MSBF24 октября 2009 г. 11:02