Перемещение папок по состоянию

Перемещение папок по состоянию

У меня много файлов Excel в одной папке, как показано ниже.

+----------------------+
| 01012019_LOC001.xlsx |
| 01012019_LOC002.xlsx |
| 01012019_LOC003.xlsx |
| 02012019_LOC001.xlsx |
| 02012019_LOC002.xlsx |
| 02012019_LOC003.xlsx |
| 03012019_LOC001.xlsx |
| 03012019_LOC002.xlsx |
| 03012019_LOC003.xlsx |
+----------------------+

дата плюс расположение комбинированная структураDDMMYYYY_LOCXXX

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

MAIN_FOLDER
|
|-LOC001
  |-01012019
  |-02012019
  |-03012019
  |
|-LOC002
  |-01012019
  |-02012019
  |-03012019
  |
|-LOC003
  |-01012019
  |-02012019
  |-03012019
|

Я могу передавать по одному за раз с помощью for /r %d in (01012019_LOC001.xlsx) do move "%d" "C:MAIN_FOLDER\LOC001\01012019\".

Но я ищу более динамичное решение. Поэтому, пожалуйста, помогите мне найти решение.

PSПримечание: даже ответа PowerShell было бы достаточно.

решение1

Для этого вам нужно будет перебрать файлы с отложенным расширением. Если только нет подпапок, из которых вы также хотите извлечь данные, я бы избегал флага, /rтак forкак он рекурсивен. Основная проблема — это разделение имени файла, так как каждая половина — это отдельный фрагмент информации. Это будет выглядеть примерно так:

@echo off

set "dir=C:\Your\Excel\File\Directory"
set "des=C:\MAIN_FOLDER"

setlocal enabledelayedexpansion
for %%A in (%dir%\*.xlsx) do (
    set "file=%%~nA"
    if not exist "%des%\!file:~-6!" md "%des%\!file:~-6!"
    if not exist "%des%\!file:~-6!\!file:~0,8!.xlsx" move /y "%dir%\%%~nxA" "%des%\!file:~-6!\!file:~0,8!.xlsx"
)

Это пакетное решение, поэтому вы можете просто скопировать и вставить его в Блокнот, а затем сохранить как файл .batвместо .txt.

Во-первых, я установил переменные для dir(каталог; где в данный момент находятся ваши файлы Excel) и des(назначение; где вы хотите создать папки и переместить файлы) — вам нужно будет отредактировать эти значения, чтобы они соответствовали вашей среде. Прежде чем что-либо делать, мы используем , setlocal enabledelayedexpansionпоскольку мы работаем с переменными, которые изменяют значения на каждой итерации цикла. forЦикл будет проходить по всем файлам Excel в верхней папке нашего каталога и назначать их параметру %%A; оказавшись внутри цикла, мы устанавливаем переменную с именем file, %%~nAкоторая является просто параметром, %%Aсокращенным до его имени файла. Мы используем один ifоператор, чтобы проверить, существует ли уже папка для этого файла — если нет, мы создаем папку с помощью md, затем мы используем другой ifоператор, чтобы проверить, существует ли файл, который мы в данный момент просматриваем, в папке, которую мы только что проверили/создали — если нет, мы перемещаем файл в папку с помощью moveи подавляем запрос на подтверждение с помощью /y( /yна самом деле это не обязательно, так как мы начинаем его с оператора if, но, по моему мнению, это лучшая практика). Команда перемещения имеет встроенную функцию переименования, поэтому мы просто используем ее, чтобы следовать желаемой схеме именования.

Самое интересное здесь — это переменные подстроки — поскольку ваши даты и местоположения представляют собой заданное количество символов, мы просто подсчитываем эти символы и извлекаем их по мере необходимости:
!file:~-6!просто берем последние шесть символов (нашу информацию LOC), а !file:~0,8!берем первые восемь символов (нашу информацию о дате). Единственное, что стоит отметить, — это использование восклицательных знаков в цикле, который использует отложенное расширение (поскольку это переменные, которые изменяются); для наших статических переменных ( dirи des) знаки процента подходят везде.

Надеюсь, это сделает то, что вы хотели, или, по крайней мере, направит вас на верный путь.

Ссылка:для,переменная подстрока,двигаться

решение2

Для полноты картины, вотPowerShellверсия:

$Source = 'C:\Source'
$Dest   = 'C:\Destination'

Get-ChildItem $source -filter *.xls | foreach{
   $FolderName = $_.Basename.Split('_')[1]
   If (!(Test-Path "$Dest\$FolderName")) {
      New-Item -Path $Dest -Name $FolderName -ItemType Directory | out-null
   }
   Move-Item $_.FullName "$Dest\$FolderName"
}

Я решил получитьЛок###string путем разделения базового имени по подчеркиванию, что само по себе возвращает двухэлементный строковый массив.1нижний индекс ссылается на второй элемент. ЕслиТест-Путьне удается, мы создаем папку, перенаправляя возврат вout-nullчтобы избежать отображения экрана. ЗатемПереместить элементделает именно то, на что похоже! :)

Получить-ChildItem

ForEach-Объект

Метод String.Split

Тест-Путь

Новый-Товар

Переместить элемент

Связанный контент