У меня много файлов 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чтобы избежать отображения экрана. ЗатемПереместить элементделает именно то, на что похоже! :)