Имя пользователя:
Пароль:
 | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Переименование каталогов

Ответить
Настройки темы
CMD/BAT - [решено] Переименование каталогов

Новый участник


Сообщения: 17
Благодарности: 0

Профиль | Отправить PM | Цитировать


Добрый день!

Помогите, пожалуйста, реализовать следующее:

В каталоге есть 10 подкаталогов типа: 100_0447, 100_0448 и пр. Нужно переименовать их, дописав в конец строки из текстового файла.

В нём, к примеру, такое
(1000)
(750)
(600)
(500)
(400)
(300)
(200)
(100)
(50)
(25)

Подкаталоги должны переименоваться так: 100_0447 (1000), 100_0448 (750) и т.д.

Пробовал так:

echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION
dir /B /A:D >dir.txt

For %%a In (1000 750 600 500 400 300 200 100 50 25) Do (Set /a cnt +=1& Set Arr[!cnt!]=%%a
)
for /f "usebackq delims=" %%i in ("dir.txt") do (Set /a index +=1
echo i= %%i
echo index= !index!
echo !Arr[%%index]!
echo !Arr[1]! !Arr[2]! !Arr[3]! !Arr[4]! !Arr[5]! !Arr[5]! !Arr[7]! !Arr[8]! !Arr[9]! !Arr[10]!
)
pause

Но почему-то, в цикле не выводятся элементы массива, хотя они определены:
Скрытый текст
b:\test>echo off
i= 100_0447
index= 1
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0448
index= 2
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0449
index= 3
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0450
index= 4
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0451
index= 5
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0452
index= 6
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0453
index= 7
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0454
index= 8
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0455
index= 9
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
i= 100_0456
index= 10
Режим вывода команд на экран (ECHO) отключен.
1000 750 600 500 400 400 200 100 50 25
Для продолжения нажмите любую клавишу . . .

Отправлено: 15:11, 20-08-2018

 

Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


В пакетных файлах отсутствует такое понятие, как «массив».

Код: Выделить весь код
@echo off
setlocal enableextensions enabledelayedexpansion

set sSourceFolder=C:\Мои проекты\0186
set sNamesFileList=C:\Мои проекты\0186\Names.txt

if exist "%sSourceFolder%\." (
	if exist "%sNamesFileList%" (
		set /a iCount = 0
		
		for /f "usebackq delims=" %%i in ("%sNamesFileList%") do (
			set sNameFileList!iCount!=%%~i
			set /a iCount += 1
		)
		
		set /a iCount = 0
		
		for /f "usebackq delims=" %%i in (
			`2^>nul dir /b /a:d "%sSourceFolder%\*.*"`
		) do (
			if defined sNameFileList!iCount! call ren "%sSourceFolder%\%%~i" "%%~i %%sNameFileList!iCount!%%"
			set /a iCount += 1
		)
	) else (
		echo Can't find name's file list file [%sNamesFileList%].
		exit /b 2
	)
) else (
	echo Can't find source folder [%sSourceFolder%].
	exit /b 1
)

endlocal
exit /b 0
Это сообщение посчитали полезным следующие участники:

Отправлено: 16:24, 20-08-2018 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 17
Благодарности: 0

Профиль | Отправить PM | Цитировать


Отсутствует, так отсутствует. Спасибо, всё получилось.

Отправлено: 16:39, 20-08-2018 | #3


Ветеран


Contributor


Сообщения: 2735
Благодарности: 1699

Профиль | Отправить PM | Цитировать


Цитата Iska:
В пакетных файлах отсутствует такое понятие, как «массив». »
Так-то оно так, но Вы используете в решение аналог массива - нумеруете переменные. Вот решение с двумя эрзац-массивами. в переменные A1...A10 занесем значения 1000 ... 25, а в переменные B1... занесём имена исходных папок для переименования.
Код: Выделить весь код
@Echo Off
	Set "Txt=1000 750 600 "500" 400 300 200 100 50 25"

	Set "BoxIn=Z:\Soft_In"
	Set "Mask=100_*.*"

	Set /A i=0
	FOR %%f IN (%Txt%) Do Call :MassIn "A" "i" %%f

	Set /A j=0
	FOR /D %%f IN ("%BoxIn%\%Mask%") DO  Call :MassIn "B" "j" "%%f"
	
	If %i% GTR %j% Set /A i=%j%
	If Not %i% EQU 0 FOR /L %%f IN (1,1,%i%) DO Call :MassRen "%%A%%f%%" "%%B%%f%%" 
GoTo :Eof

:MassIn
	Set /A %~2+=1
	Call Set /A @i=%~2
	Set "%~1%@i%=%~3"
GoTo :Eof

:MassRen
	Ren %2 "%~nx2 (%~1)"
GoTo :Eof
Я не стал считывать номера из текстового файла - для моего решения это не принципиально. Хотя не проблема: Можно эти номера аналогичным путём занести в эрзац-массив из текстового файла.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.

Это сообщение посчитали полезным следующие участники:

Отправлено: 19:04, 20-08-2018 | #4


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Цитата megaloman:
Так-то оно так, но Вы используете в решение аналог массива - нумеруете переменные. Вот решение с двумя эрзац-массивами. »
С такой трактовкой — эрзац-массив — согласен. Насчёт «аналога массива» — нет, не могу согласиться: никак не аналог, просто отдельные переменные.

Отправлено: 19:31, 20-08-2018 | #5


Новый участник


Сообщения: 17
Благодарности: 0

Профиль | Отправить PM | Цитировать


Но мне всё равно непонятно, почему значения echo !Arr[1]! !Arr[2]! !Arr[3]! !Arr[4]! !Arr[5]! !Arr[5]! !Arr[7]! !Arr[8]! !Arr[9]! !Arr[10]! выводятся, а echo !Arr[%%index]! - нет.
Может я неправильно передаю индекс? С этими процентами, восклицательными знаками и пр. - постоянная путаница.

Отправлено: 02:08, 21-08-2018 | #6


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Цитата shraybikus:
Но мне всё равно непонятно, почему значения echo !Arr[1]! !Arr[2]! !Arr[3]! !Arr[4]! !Arr[5]! !Arr[5]! !Arr[7]! !Arr[8]! !Arr[9]! !Arr[10]! выводятся, а echo !Arr[%%index]! - нет. »
Ну, давайте начнём.

1.
Код: Выделить весь код
setlocal enableextensions
setlocal enabledelayedexpansion
— технически допустимо, но логически неверно. Таким образом Вы задаёте сначала один локальный контекст, затем, тут же, ещё один. В этом нет смысла. Правильным будет использование одной команды setlocal:
Код: Выделить весь код
setlocal enableextensions enabledelayedexpansion
2. В условии у Вас:
Цитата shraybikus:
строки из текстового файла.
В нём, к примеру, такое
(1000)
(750)
(600)
(500)
(400)
(300)
(200)
(100)
(50)
(25) »
а в коде эти строки напрямую заданы строкой:
Код: Выделить весь код
For %%a In (1000 750 600 500 400 300 200 100 50 25) Do (Set /a cnt +=1& Set Arr[!cnt!]=%%a)
Для читабельности лучше не стесняться использовать фолдинг, наподобие:
Код: Выделить весь код
for %%i in (1000 750 600 500 400 300 200 100 50 25) do (
	set /a cnt += 1
	set Arr[!cnt!]=%%i
)
3.
Цитата shraybikus:
почему значения echo !Arr[1]! !Arr[2]! !Arr[3]! !Arr[4]! !Arr[5]! !Arr[5]! !Arr[7]! !Arr[8]! !Arr[9]! !Arr[10]! выводятся »
Потому что переменные окружения !Arr[1]! и т.д. определены и корректно раскрываются в свои значения. Причём здесь нет никакой необходимости использовать отложенное раскрытие, достаточно простого:
Код: Выделить весь код
echo %Arr[1]% %Arr[2]% %Arr[3]% %Arr[4]% %Arr[5]% %Arr[5]% %Arr[7]% %Arr[8]% %Arr[9]% %Arr[10]%
4.
Цитата shraybikus:
а echo !Arr[%%index]! - нет. »
Потому что непонятно, что Вы хотите сделать. У нас определена переменная окружения index, у нас определена переменная цикла разбора i.

Первую можно получить по !index! [или call %%index%%] (вот здесь отложенное раскрытие [или двойное обычное раскрытие] уже нужно, потому что её значение ранее задаётся внутри тех же операторных скобок). Вторая доступна по %%i. А что у нас?

А у нас так:
Код: Выделить весь код
echo !Arr[%%index]!
Вы думаете, что %%index — переменная окружения index? Это не так. В этом коде нет переменной окружения index. Зато есть переменная цикла разбора %%i. Которая раскроется в своё значение из содержимого файла dir.txt — сначала в 100_0447, затем в 100_0448 и т.д. Таким образом, интерпретатор команд при попытке отложенного раскрытия сначала увидит переменную окружения Arr[100_0447ndex], которая, разумеется, не существует, затем переменную окружения Arr[100_0448ndex], которая тоже не существует, и т.д.

Как это можно обойти? Например, так, как в моём коде выше:
Код: Выделить весь код
if defined sNameFileList!iCount! call ren "%sSourceFolder%\%%~i" "%%~i %%sNameFileList!iCount!%%"
Для Вашего кода это может выглядеть как:
Код: Выделить весь код
call echo %%Arr[!index!]%%
Это сообщение посчитали полезным следующие участники:

Отправлено: 08:09, 21-08-2018 | #7


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1235
Благодарности: 518

Профиль | Отправить PM | Цитировать


Цитата Iska:
Насчёт «аналога массива» — нет, не могу согласиться: никак не аналог, просто отдельные переменные. »
Верно, набор нумерованных переменных - не есть массив и даже не аналог массива... но, что интересно, как-то столкнулся с реализацией массивов именно на cmd... тогда ещё подумалось, вот ведь у человека насколько огромным желание должно было быть, чтобы наваять такое! Особенно, если учесть, что существуют готовые и более простые в использовании, пусть и не на cmd.
Но всё равно, это ведь имеет право на жизнь, особенно если случай с ОС "запущенный" и использование чего-то внешнего проблематично... вот, откопал таки ссылку

-------
scio me nihil scire. Ѫ


Отправлено: 13:35, 21-08-2018 | #8


Новый участник


Сообщения: 17
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
вот, откопал таки ссылку »
Я её видел, и даже пытался использовать без самой функции, потому что ссылка на неё лишь в конце статьи. Народ даже ООП на батниках мутит.

Отправлено: 13:58, 21-08-2018 | #9


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
вот, откопал таки ссылку »
Дело в том, что это не массив. В принципе. Не массив, и всё тут. Потому как любая реализация подобного эрзац-массива будет обставлена таким количеством оговорок и ограничений (чего только стоит отдельная переменная окружения для хранения размера массива), что нет смысла как-то сим заморачиваться.

Ну, и в скобках отмечу, что:
Цитата:
Надо сказать пару слов о процедурах, возвращающих значение. Т.к. в батниках нет возможности вернуть значение из процедуры (будем так называть то, что вызывается через call),
— неверно. Есть возможность .

Отправлено: 14:30, 21-08-2018 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Переименование каталогов

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - Синхронизация каталогов Makzs Скриптовые языки администрирования Windows 4 03-11-2009 15:56
синхронизация каталогов Saduga Microsoft Windows NT/2000/2003 4 20-08-2008 16:07
дерево каталогов slaine Вебмастеру 8 26-02-2006 20:45
Разорхивация каталогов Neto Хочу все знать 4 04-12-2003 22:38
Обновление каталогов в проводнике soloIL Microsoft Windows 95/98/Me (архив) 1 16-05-2003 08:36




 
Переход