Приношу извинения за слишком долгое отсутствие постов в блоге, лето, дела, <добавить прочие отмазы по вкусу>… Но забрасывать блог я разумеется пока не собираюсь, так что не торопитесь отписываться
Итак, совершенно случайно, на просторах интернета, я наткнулся на такую задачку – http://community.livejournal.com/ru_sysadmins/1134170.html. По условиям требовалось переместить файлы разложенные в структуре формата
x:\incoming\<year>\<month>\<date>\<<datatype>-<year>-<department>>\
на другой диск, в уже другом формате
y:\<year>\<department>\<datatype>\<<datatype>-<year>-<department>>\
К счастью задачка решалась достаточно несложно, и в комментах было произнесено слово PowerShell
так что я быстренько набросал решение. Думаю технология может пригодиться не только автору, поэтому размещаю копию решения и здесь, с комментариями.
#Получаем содержимое папки x:\incoming и подпапок, выбираем только файлы, и для каждого из них... dir x:\incoming -recurse | where {! $_.psiscontainer} | foreach { #Если его полный путь подпадает под регулярное выражение, то им же разбирается на компоненты #Компоненты помещаются в специальный массив $matches if ($_.fullname -match 'x:\\incoming\\([^\\]+)\\([^\\]+)\\([^\\]+)\\([^\-]+)-[^\-]+([^\\]+)\\') { #Присваиваем значения из $matches переменным с человекопонятными именами, для удобства $year,$month,$date,$type,$departament = $matches[1..5] #Составляем путь к новому каталогу для файла из этих переменных $newpath = "y:\$year\$departament\$type\$type-$year-$departament" #Если каталог еще не существует, то... if (!(test-path $newpath)) { #...создаём его new-item -type directory $newpath -force } #Копируем файл в новое место с выводом информации на экран copy $_ $newpath -verbose } else { #Если путь не подпал под регулярное выражение, то выводим предупреждение write-warning "Path $($_.fullname) not match regular expression" } }
Вот и всё. К сожалению не проверял, лень было создавать тестовую структуру, но вроде должно работать
Если встретите какие то ошибки – сообщайте









Здравствуйте, у меня возник вопрос на который я пока не могу найти ответа:
«Срок жизни» переменной $_? То есть если внутри конвеера вложен еще один конвеер (например циклом) эта переменная переносится из первого конвеера или генерируется во втором?
Комментарий от inhalator — 9.7.2009 @ 16:32
Если во вложенном скриптблоке создаётся новая переменная то из вложенного скриптблока видна только она, а внешнаяя недоступна (но разумеется не перезаписывается):
1..3 | foreach {4..6 | foreach {$_}; $_}
Если же в скриптблоке не назначается значение для $_ то видна внешняя переменная:
1..3 | foreach {}
Вобщем механизм видимости практически как и у любых других переменных. Вот здесь можно почитать – http://technet.microsoft.com/en-us/library/dd315289.aspx
Комментарий от Xaegr — 9.7.2009 @ 16:40
Я скрипт ваш погонял на стенде, немного изменив систему разборки старого месторасположения.
1. В процессе отладки убрал создание директорий, т.к. он при копировании создаёт её сразу.
2. Скрипт копирует пустые папки, т.е. файлы не переносятся. Надо к copy добавить -recurse -force
Комментарий от inhalator — 10.7.2009 @ 17:27
Начали проверять процедуру move, оказалось, что она не работает между томами (для директорий). Есть ли способ это обойти, кроме copy/delete?
Комментарий от inhalator — 24.7.2009 @ 18:59
inhalator: На самом деле перемещение лишь изменяет записи в таблице размещения файлов, поэтому и перемещение между томами невозможно. Причем это касается не только PowerShell, практически любые утилиты перемещающие между дисками на самом деле сначала копируют данные, и затем удаляют оригинал.
Комментарий от Xaegr — 24.7.2009 @ 19:06