Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Переименование. Заменить часть символов в имени файла. (http://forum.oszone.net/showthread.php?t=348749)

epoddubniy 14-05-2021 00:16 2957819

Переименование. Заменить часть символов в имени файла.
 
Здравствуйте.
В директории есть файлы .xls, имена которых заканчиваются на "_21"
Помогите пожалуйста их переименовать на "_2021"
Также прошу помощи, как в заданной директории у файлов, у которых в имени встречается символ "." заменить на символ "_"
Заранее Спасибо!

Iska 14-05-2021 17:03 2957933

epoddubniy, Вам обязательна на пакетных файлах реализация? Powershell не подойдёт?

alpap 14-05-2021 17:11 2957934

да я вообще не понимаю ТС, он уже создавал тему в которой присутствовал момент переименования и был показан в коде, только создать новую тему не лень. а зайти в свою предыдущую лень - абсурд.

alpap 14-05-2021 17:43 2957937

вот прямолинейный (и даже нет, я из предыдущей темы ТС знаю что 21 и 2021 это год, а не просто цифры, поэтому и в этой теме условие задачи неполное или неверное) подход:
Код:

$a = @(
  '408aaaa_21.xls'
  '4082222_21.xls'
)

$oldPsf = '_{0:yy}'  -f (Get-Date)
$newPsf = '_{0:yyyy}' -f (Get-Date)

$a|% {$_ -Replace $oldPsf, $newPsf}

но для файлов в папке код возможно будет другим, а для [символ "." заменить на символ "_"] еще более другим, так как тут надо учитывать расширение, которое (если есть) тоже начинается с "."
---
и я смотрю мы тут ему уже не раз что-то переименовывали. Может проще вскрыть карты и описать задачу целиком, только по человечески, а не как раньше: Происходит это потом это ...
Задача ставится так
---
Директория такая-то - есть, создана
С сервера или откуда там приходят файлы в такую-то директорию с такой-то интенсивностью с такой-то маской
Запуск (соответственно проверка наличия файлов) кода будет производится (возможно из планировщика) вручную раз в месяц (неделю)
Надо отобрать по маске или по дате файлы все или по столько-то штук из общей папки и разложить в другие папки (если их нет, то создать, имена папок должны содержать часть имени файла и дату из имени файла или свойства файла)

megaloman 14-05-2021 21:32 2957950

Цитата:

Цитата epoddubniy
В директории есть файлы .xls, имена которых заканчиваются на "_21"
Помогите пожалуйста их переименовать на "_2021" »

Код:

@Echo Off
cls
        Set "BoxIn=Z:\Box_In"
        Set "Find=_21.xls"
        Set "Repl=_2021.xls"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`) Do (
                Set "Name=%%~nxf"
                Call Ren "%BoxIn%\%%f" %%Name:%Find%=%Repl%%%
        )
pause
Exit /B

Если замену надо сделать для произвольного года 2010...2029
Код:

@Echo Off
cls
        Set "BoxIn=Z:\Box_In"
        Set "Find=^.*_[1-2][0-9]\.xls$"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*.*" ^| findstr.exe /R /I /C:"%Find%"`) Do (
                Set "Name=%%~nxf"
                Call Ren "%BoxIn%\%%f" "%%Name:~0,-6%%20%%Name:~-6%%"
        )
pause
Exit /B

Цитата:

Цитата epoddubniy
как в заданной директории у файлов, у которых в имени встречается символ "." заменить на символ "_" »

Код:

@Echo Off
cls
        Set "BoxIn=Z:\Soft_In"
        Set "Find=."
        Set "Repl=_"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*.*"`) Do (
                Set "Name=%%~nf"
                Call Ren "%BoxIn%\%%f" "%%Name:%Find%=%Repl%%%%%~xf"
        )
pause
Exit /B

Цитата:

Цитата alpap
Может проще вскрыть карты и описать задачу целиком »

Цитата:

Цитата «Бе́лое со́лнце пусты́ни»
Семён: Тебя как, сразу прикончить, или желаешь помучиться?
Сухов: Лучше, конечно, помучиться.

А вдруг у epoddubniy похвальное желание самому получить конечный результат, и он/она использует наше участие для обучения :)

epoddubniy 16-05-2021 10:26 2958057

Цитата:

Цитата alpap
да я вообще не понимаю ТС, он уже создавал тему в которой присутствовал момент переименования и был показан в коде, только создать новую тему не лень. а зайти в свою предыдущую лень - абсурд. »

простите, alpap, я учусь...читая код на cmd потихоньку хоть что-то начинает становиться понятным, а копаться в powershell в его синтаксисе, думаю мне еще очень рано, нужно хотя бы "винтаж" более-менее понимать (да и вообще, хотя бы что-то) а потом уже на другое переходить. А в Вашем коде я элемент переименования не разглядел по незнанию. Благодарю за помощь, прошу прощения. В этой теме я не стал про переименование писать, т.к. это не совсем относится к той теме, ведь там про перемещение файлов, поэтому решил отдельно создать топик, чтобы не было нагромождения.
Цитата:

Цитата Iska
epoddubniy, Вам обязательна на пакетных файлах реализация? Powershell не подойдёт? »

Спасибо.
Цитата:

Цитата alpap
Директория такая-то - есть, создана
С сервера или откуда там приходят файлы в такую-то директорию с такой-то интенсивностью с такой-то маской
Запуск (соответственно проверка наличия файлов) кода будет производится (возможно из планировщика) вручную раз в месяц (неделю)
Надо отобрать по маске или по дате файлы все или по столько-то штук из общей папки и разложить в другие папки (если их нет, то создать, имена папок должны содержать часть имени файла и дату из имени файла или свойства файла) »

Спасибо, alpap, учту на будущее.
Цитата:

Цитата megaloman
А вдруг у epoddubniy похвальное желание самому получить конечный результат, и он/она использует наше участие для обучения »

Так - точно, megaloman,

Код:


       
Цитата:

       
       
               
       
       

                       

                       
                               

                                        Цитата megaloman
                                       
                               

                               
@Echo Off
cls
 Set "BoxIn=Z:\Box_In"
 Set "Find=_21.xls"
 Set "Repl=_2021.xls"
For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`) Do (
 Set "Name=%%~nxf"
 Call Ren "%BoxIn%\%%f" %%Name:%Find%=%Repl%%%
 )
pause
Exit /B »

                       
                       

               


почему-то интерпретатор вылетает, если в коде этот кусок
Код:

Do (
                Set "Name=%%~nxf"
                Call Ren "%BoxIn%\%%f" %%Name:%Find%=%Repl%%%

если его заменить на
Код:

echo %%f
то интерпретатор не вылетает и выводятся имена файлов в каталоге с расширением

megaloman, скажите пожалуйста, правильно ли я понял кусок кода?
Код:

For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`) Do (
 Set "Name=%%~nxf"
 Call Ren "%BoxIn%\%%f" %%Name:%Find%=%Repl%%%
 )

1) 2^>nul - поток ошибок не выводится в окно интерпретатора
2) Dir /B /A:-D "%BoxIn%\*%Find%" - получаем список имен файлов в целевой директории, у которых имя имеет маску "*_21"
3) Set "Name=%%~nxf" - у каждого файла оставляем только имя и расширение, путь отбрасывается
4) Call Ren - вызываем команду Rename
5) Call Ren "%BoxIn%\%%f" - осуществляем переименование в каталоге BoxIn файлов %%F, а так как в переменной цикла %%F сохранено значение имен файлов с маской "*_21", то они по очереди будут подставляться
6) %%Name:%Find%=%Repl%%% - вот это - не понял :-( Понимаю, что синтаксис команды rename подразумевает переименование того, что было "%BoxIn%\%%f" на то, что будет %%Name:%Find%=%Repl%%%, но то, как это получается - не понятно
почему у %%Name двойной знак процента, как у переменной цикла, почему потом стоит двоеточие (что это за синтаксис и для чего он используется) равенство в выражении означает, что присваивается значение %repl%, ну то есть, если я правильно понимаю, каждый %find% меняется на %repl% а для чего после %repl% стоят двойные знаки процента?

Заменил
Код:

For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`)
на
Код:

For /f "tokens=*" %%f In ('Dir /B /A:-H "%BoxIn%\*%Find%"')
скрипт отработал, файлы переименовались, но осталась неясность с
Цитата:

почему у %%Name двойной знак процента, как у переменной цикла, почему потом стоит двоеточие (что это за синтаксис и для чего он используется) равенство в выражении означает, что присваивается значение %repl%, ну то есть, если я правильно понимаю, каждый %find% меняется на %repl% а для чего после %repl% стоят двойные знаки процента?

megaloman 16-05-2021 14:15 2958076

epoddubniy, Давайте договариваться: Вы берёте мой код, сохраняете его в текстовый файл с расширением .bat в 866 кодировке и запускаете его на выполнение. Потом по факту рассказываете, что работает, а что брыкается.
Я еще раз проверил исполнение моих кодов - работают.
Разъяснение кода (опять же - все коды примеров сохраняем в файл с расширением .bat и запускаем на выполнение)

Dir /B /A:-D "%BoxIn%\*%Find%" - получаем список имен файлов в целевой директории, у которых имя имеет маску "*_21.xls"
Обсудим поведение переменных в цикле (извините, если излагаю известное).
Для отладки, вот код:
Код:

@Echo Off
cls
        Set "BoxIn=Z:\Box_In"
        Set "Find=_21.xls"
        Set "Repl=_2021.xls"

        Set "Name=kuku"
        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`) Do (
                Set "Name=%%~nxf"
                Echo %Name%===="%%~nxf"
        )
Echo %Name%
pause
Exit /B

Видим, что с нашей точки зрения переменная %Name% раскрывается неправильно.
Echo %Name%===="%%~nxf" выдаёт значение %Name% определённое до цикла, а после цикла
Echo %Name% выдаст последнее значение, присвоенное %Name% в цикле.
Такие реалии раскрытия переменной в цикле.
Чтобы раскрытие переменной работало корректно, применим вместо
Echo %Name%===="%%~nxf" ------> Call Echo %%Name%%===="%%~nxf"
Проделайте и убедитесь, что работает ожидаемо.
То есть, Name заключили с двух сторон в двойные %% и вызвали команду через Call
Альтернатива
Код:

@Echo Off
cls
SetLocal EnableExtensions EnableDelayedExpansion
        Set "BoxIn=Z:\Box_In"
        Set "Find=_21.xls"
        Set "Repl=_2021.xls"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\*%Find%"`) Do (
                Set "Name=%%~nxf"
                Echo !Name!===="%%~nxf"
        )
pause
Exit /B

Но я стараюсь не применять этот способ, так как если в имени присутствуен "!" то код корректно не отработается.

Аналогичная история с Ren. Но тут еще надо почитать хелп к Set /?
Цитата:

Цитата хелп к Set
Подстановка переменной среды может быть расширена следующим образом:

%PATH:str1=str2%

расширит действие переменной среды PATH, заменяя каждое вхождение "str1" в
расширенном результате на "str2". "str2" может быть пустой строкой для
эффективного удаления вхождений "str1" из расширенного вывода. "str1" может
начинаться со звездочки, и в этом случае это будет соответствовать любому
началу расширенного вывода до первого вхождения оставшейся части "str1".

У нас переменняя Name, мы договорились, что её надо использовать как %%Name%%,
str1 это %Find%, str2 это %Repl%
То есть в имени файла подстроку _21.xls заменим на _2021.xls, чего Вы и домогались.

epoddubniy 20-05-2021 15:54 2958527

Цитата:

Цитата megaloman
epoddubniy, Давайте договариваться: Вы берёте мой код, сохраняете его в текстовый файл с расширением .bat в 866 кодировке и запускаете его на выполнение. Потом по факту рассказываете, что работает, а что брыкается.
Я еще раз проверил исполнение моих кодов - работают. »

Понял. Спасибо, megaloman,


Время: 07:41.

Время: 07:41.
© OSzone.net 2001-