Cmd обрезать имя файла

Обновлено: 05.07.2024

У меня есть сервер Windows Server 2003, который имеет целую кучу имен файлов, которые необходимо переименовать. По сути, мне просто нужно заменить все - (дефисы) на _ (подчеркивания), независимо от того, где они находятся в имени файла. Предположим, что нет дубликатов.

Я могу сделать это на своем Mac с помощью небольшого сценария, но файлы слишком большие и сумасшедшие, чтобы передать их на мой Mac, переименовать, а затем вернуться на сервер. Возможно ли сделать это в командной строке Windows, не загружая переименователь или дополнительное программное обеспечение?

Из командной строки - при условии, что все ваши файлы находятся в одном каталоге:

ОДИН ЛАЙНЕР

for /f "tokens=* delims= " %i in ('dir /b "*.txt"') do Set LIST=%i& set LIST | ren "%

Имейте в виду, что это один выстрел на окно командной строки. Это означает, что если вы отмените это по какой-либо причине, вам нужно будет открыть другую командную строку и запустить снова.

Пакетный файл для замены одного символа в имени файла другим символом

Если вы должны сделать это сами с командным файлом, будьте супер осторожны! Пакетные сценарии не имеют кнопки "отменить". Если вы выполняете свой скрипт bat, который рекурсивно применяется ко всем файлам где-то вроде C: вы просто переименуете каждый файл на своем компьютере, и он сразу же перестанет работать и не сможет загрузиться. Вам придется сделать полную переустановку ОС. Всегда имейте резервную копию!

Сначала вам нужно решить, хотите ли вы, чтобы пакетный файл работал с одним файлом? Работать со всеми файлами в каталоге? Или сделать это рекурсивно (все файлы / папки в каталоге). Вот несколько указателей:

Пакетный файл для замены всех подчеркиваний _ на букву M для всех файлов в текущем каталоге

Поместите это в пакетный файл с именем change_underscores_in_this_directory.bat

Выполните его, и все файлы в этом каталоге с подчеркиванием будут заменены на «М».

Используйте пакетный файл, чтобы заменить пробелы ничем (удаляя пробелы):

Используйте пакетный файл для замены пробелов подчеркиванием, рекурсивно:

Удалить часть имени файла
Нужна помощь. У меня имеется несколько папок, которые называются по шаблону.

Удалить часть имени в файлах
Имеется очень много файлов с именем, на конце которых такое "<пробел>(Rus conflicted copy.


Удалить часть имени файлов
Здравствуйте! Помогите пожалуйста, как убрать окончание файлов (.1024 .512) у меня много файлов с.

По какому критерию определять, где заканчивается нужное и начинается ненужное? По какому критерию определять, где заканчивается нужное и начинается ненужное? Например по этому "(abc12).123" потому что у меня 2 типа это: "(abc12).123" и "(cba21).321" Например по этому "(abc12).123" потому что у меня 2 типа это: "(abc12).123" и "(cba21).321" У меня похожая проблема, разъясните кто-нибудь, пожалуйста, этот код, чтоб я мог переделать его под свою задачу. Если не сложно. Я плохо балакаю в батниках

Решение

Добавлено через 23 минуты
Вот для желающих код для решения моей задачи от FraidZZ:

Задача состояла в следующем: батник запускается и создает рядом с собой файл *.txt, где * - номер по порядку.
То есть каждый раз создается файл n+1.txt

Я только начинаю разбираться в командах CMD, опишу мое видение того, как работает этот батник:

set n=0 //понятно - устанавливаем счетчик-переменную
:again // это, должно быть, точка перехода для goto
set /a n+=1 //Задал в командной строке "help set" - узнал, что ключ "/a" (цитирую) - "указывает, что значение
//справа является числовым выражением, значение которого вычисляется". Далее мы увеличиваем
//счетчик n на один и
if exist "%n%.txt" //если файл с таким номером уже существует
goto again //повторяем цикл again
type nul>"%n%.txt" //здесь TYPE - вывод содержимого файла на экран, а "nul", похоже, означает нулевое значение
//а с помощью ">" переводим вывод в файл "%n%.txt"

нужен батник, который бы переименовывал по следующему шаблону:

из имени файла с конца удалял заданное число символов, например 32, в итоге
переименованный файл должен принять вид:

нашел как переименовывать просто файлы:

но никак не могу понять, как удалять символы с конца имени файла в данном случае.

alex_diablo

Активный пользователь

вобщем, поковырялся и сделал вот так:


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

Dragokas

Very kind Developer
alex_diablo, все Вы нормально сделали.
Двойное раскрытие переменной можно организовать так:

alex_diablo

Активный пользователь

а как сделать, чтобы не нужно было высчитывать количество символов? ну вот например, в имени файла есть 4 символа нижнего подчеркивания.
и нужно все символы, которые после последнего знака подчеркивания - убрать, т.е. файл 456123agents_preview_pack_004_BC15F9146A415178B95BE92EB26DD92F-56.unity3d
после переименования должен иметь вид: 456123agents_preview_pack_004.unity3d

пробовал задействовать вот этот вариант:

но что то не получается.
в идеале - нужно иметь возможность в переменную задать количество подстрок, на которые будет разбиваться имя файла и переименовывать в соответствии с необходимым
количеством разделителей (в данном случае - символ нижнего подчеркивания)

надеюсь понятно объяснил.

Dragokas

Very kind Developer
А не получится ли так, что среди тех файлов, что нужно переименовать попадется
456123agents_preview_pack_004
у которого соответственно урежется часть _004
?

alex_diablo

Активный пользователь
alex_diablo, все Вы нормально сделали.
Двойное раскрытие переменной можно организовать так:

а в данной версии кода хотелось бы всю команду

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

Dragokas

Very kind Developer
2. Можно как-то привязаться к кол-ву знаков подчеркивания,
или может получится, что таких знаков = 3, а строку все равно нужно урезать до 2-ух знаков подчеркивания ?

alex_diablo

Активный пользователь
А не получится ли так, что среди тех файлов, что нужно переименовать попадется
456123agents_preview_pack_004
у которого соответственно урежется часть _004
? нет. т.к. заведомо известно, что в одно время в одной папке находятся файлы, именнованные все по одному шаблону. но в разное время количество разделителей может быть разное, поэтому и нужна возможность задать количество разделителей, чтобы подстраивать скрипт.

alex_diablo

Активный пользователь
2. Можно как-то привязаться к кол-ву знаков подчеркивания,
или может получится, что таких знаков = 3, а строку все равно нужно урезать до 2-ух знаков подчеркивания ?

поясню задачу: есть файлы вида: agents_preview_pack_002_1171C57D8808635BA4F8AFAEA5149D8D.unity3d
agents_preview_pack_004_1171C57D8808635BA4F8AFAEA5149D8D.unity3d
agents_preview_archive_010_1171C57D8808635BA4F8AFAEA5149D8D.unity3d

вот в них нужно убирать хеш (символы вида 1171C57D8808635BA4F8AFAEA5149D8D)

т.е. после манипуляций переименования все файлы должны принять вид:
agents_preview_pack_002
agents_preview_pack_004
agents_preview_archive_010

Как удалить определенные символы или заменить некоторые символы другими символами с помощью выполнения пакетного файла, для имен файлов всех файлов в папке Windows на одном дыхании, Есть ли команда DOS для этого?

используйте PowerShell, чтобы сделать что-нибудь умнее для приглашения DOS. Здесь я показал, как пакетно переименовать все файлы и каталоги в текущем каталоге, содержащие пробелы, заменив их на _ подчеркивания.

EDIT:
дополнительно the Where-Object команда может использоваться для фильтр из недопустимых объектов для последовательных (command-let). Ниже приведены некоторые примеры, иллюстрирующие гибкость, которую он может себе позволить:

пропустить любые файлы документов

для обработки только каталогов (до версии 3.0)

PowerShell версии 3.0 введена новая Dir флаги. Вы также можете использовать Dir -Directory там.

пропустить все файлы, уже содержащие символ подчеркивания (или какой-либо другой символ)

однострочная команда в Windows PowerShell для удаления или переименования определенных символов будет выглядеть следующим образом. (здесь пробелы заменяются подчеркиванием)

ответы PowerShell хороши, но команда Rename-Item не работает в одном целевом каталоге, если все ваши файлы не имеют нежелательного символа в них (сбой, если он находит дубликаты).

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

этот файл может помочь, но он имеет некоторые ограничения. Символы имени файла = и % не могут быть заменены (переход из памяти здесь), и ^ в именах файлов также может быть проблемой.

в этой части %newname: =_% в каждой строке нижнего блока он заменяет символ после : с персонажем после = так как он стоит, куча символов будет заменена подчеркиванием.

удалить echo для активации команды ren как это просто печатать команды в окне консоли, пока вы делаете.

он будет обрабатывать только текущую папку, если вы не добавите /s к части команды DIR, а затем он будет обрабатывать все папки под текущим тоже.

чтобы удалить определенный символ, удалите символ после знака=. В %newname:z=% такая запись удалит все символы z (без учета регистра).

Я бы рекомендовал для этого. Тип ren /? в командной строке для получения дополнительной помощи.

1 EXIT /b for %%a in ("A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i" "J=j" "K=k" "L=l" "M=m" "N=n" "O=o" "P=p" "Q=q" "R=r" "S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z" "А=а" "Б=б" "В=в" "Г=г" "Д=д" "Е=е" "Ж=ж" "З=з" "И=и" "К=к" "Л=л" "М=м" "Н=н" "О=о" "П=п" "Р=р" "С=с" "Т=т" "У=у" "Ф=ф" "Х=х" "Ц=ц" "Ч=ч" "Ш=ш" "Щ=щ" "Ь=ь" "Ы=ы" "Ъ=ъ" "Э=э" "Ю=ю" "Я=я") do ( call set %

ЗАМЕНА ОДНОЙ ПОДСТРОКИ НА ДРУГУЮ В ФАЙЛЕ

В результате, в папке, где будет запущен приведенный выше текст, создастся файл sbs2.com.
Возможно, вы будете приятно удивлены его размером - 659 БАЙТ!
Те, кому вышеприведенные изыски кажутся излишними, могут скачать готовую утилиту здесь.
Использование:
sbs2.com 0 "Old String" "New String" < infile > outfile
Осуществляется замена всех вхождений Old String на New String в файле infile. Результат запишется в файл outfile.

Такую задачу можно решить без использования сторонних программ, только средствами bat !
Ниже приведен пример с использованием локальной процедуры txtrepl

setlocal ENABLEDELAYEDEXPANSION echo off call :txtrepl end finish C:\1\24i.bat C:\1\24i.ba1 pause exit :txtrepl rem param - find, repl, from, to set FINDTXT=%1 set REPLTXT=%2 if EXIST %3 ( set FILEFROM=%3 ) else ( echo error. Not found file %3 pause exit ) set FILEOUT=%4 set COUNT=0 for /F "tokens=*" %%n in (!FILEFROM!) do ( set /A COUNT=!COUNT!+1 set LINE=%%n set TMPR=!LINE:%FINDTXT%=%REPLTXT%! if !COUNT! == 1 ( Echo !TMPR!>!FILEOUT! ) else ( Echo !TMPR!>>!FILEOUT! ) ) exit /b rem end of proc

Вывод на экран, в файл текста без перевода строки

В bat/cmd командах не предусмотрена возможность вывода данных без перевода строки. Но для решения такой задачи можно использовать некую уловку.
Команда set с параметром, предусматривающим ввод данных с экрана, позволяет вывести подсказку для ввода без перевода строки. Вот этим мы и воспользуемся.
<nul set /p a=text В данном случае, слово text (а здесь может быть и переменная) будет выведено но экран без перевода строки. Значение переменной a при этом не будет изменено (если это для вас важно).
Соответственно, для вывода текста в файл без перевода строки используется конструкция:
<nul set /p a=text>b.txt

Использование этого приема в сочетании с символом backspace (код 08) позволяет сделать вывод на экран изменяемого текста и как вариант - "вращающейся палки".

Вычисление длины строковой переменной

В bat/cmd командах нет функции, позволяющей вычислять длину строковой переменной. А такая задача возникает не так уж и редко. Однако средств командного языка достаточно, для того что бы решить такую задачу, не прибегая к использованию специальных программ. Рассмотрим несколько вариантов решения данной задачи:

1 :startvarcount if not defined var exit /b set var=%var:

1% set /a %2+=1 goto startvarcount exit /b

set st=abcdefghijklmnopqrstuvwxyz . call :var_сount2 %st% count2 echo %count2%

Еще один вариант вычисления длины строковой переменной:

:StringLen :: ----------------------- :: Нахождение длины строки :: ----------------------- :: %1 - текстовая строка :: ----------------------- Set $StringLen=0 Set $StringBuf=%

1" GoTo :EOF :StringLenLoop Set /A $StringLen+=1 Call Set $StringChr=%%$StringBuf:

%$StringLen%%% If ""=="%$StringChr%" GOTO :EOF GoTo :StringLenLoop

Еще один способ определения длины строки, как ни странно - достаточно быстрый:

n0.tmp" For %%i In ("%TEMP%\%

n0.tmp") Do Set /A z=%%

Ну и, наконец, решение, поразившее меня своей математической лаконичностью:

:strLen string len -- returns the length of a string :: -- string [in] - variable name containing :: the string being measured for length :: -- len [out] - variable to be used :: to return the string length :: Many thanks to 'sowgtsoi', but also 'jeb' :: and 'amel27' dostips forum :: users helped making this short and efficient :$created 20081122 :$changed 20101116 :$categories StringOperation :$source http://www.dostips.com ( SETLOCAL ENABLEDELAYEDEXPANSION set "str=A!%

1!"&rem keep the A up front to ensure we rem get the length and not the upper bound rem it also avoids trouble in case of empty string set "len=0" for /L %%A in (12,-1,0) do ( set /a "len|=1%<<%%A" for %%B in (!len!) do ^ if "!str:

1<<%%A" ) ) ( ENDLOCAL & REM RETURN VALUES IF "%

set "string=12345678901234 " call :strLen string len echo len=%len%

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

@echo off setlocal ENABLEEXTENSIONS SetLocal EnableDelayedExpansion set "string=123456789012345678901" call :strLen string len echo len=%len% pause exit :strLen string len :: - string [in] - variable name containing the string :: -- len [out] - variable to be used to return the string length SETLOCAL ENABLEDELAYEDEXPANSION set /a nn=10 & rem max length string = 2^^nn. rem If nn=10 - max length=1024 set /a mmin=0 set /a mmax=1"<<"%nn% set "str=Q!%1!" for /L %%A in (%nn%,-1,1) do ( set /a BB = ^(!mmin! + !mmax!^) ">>" 1 call set sim=%%str:

!BB!,1%% if "!sim!" == "" ( set /a mmax=!BB!) else ( set /a mmin=!BB! ) ) ENDLOCAL & SET /a %

2=%mmin% EXIT /b %mmin%

Получение подстроки.

Если смещение начала подстроки и ее длина являются константами - здесь все достаточно просто и аналогичный пример рассматривался выше:

Прошу прощения, если в качестве значения переменной str я опубликовал чей-то пароль )).
Если же одна или обе эти величины - переменные, то решение будет не столь простое.
Здесь встретиться возможно не совсем обычное применение команды CALL. Немного глубже об этом на странице Полезное в разделе Особенности использования команды CALL. Там же рассмотрен и этот пример.
Итак, рассмотрим возможные решения:

SetLocal EnableDelayedExpansion set str=123qwerty456 set n1=3 set n2=6 Set d2=!str:

Или как вариант предыдущего

setlocal ENABLEEXTENSIONS SetLocal EnableDelayedExpansion set str=zaq12wsx set n1=3 set n2=6 call :SUBSTRING str,%n1%,%n2% echo %SUBD% . :SUBSTRING set SUBD=!%1:

Удаление ведущих и замыкающих пробелов.

:ALLTRIM :: ----------------------- :: Krasner B. :: ----------------------- :: %1 - var with txt string :: ----------------------- SetLocal EnableDelayedExpansion set /a firstnoblank=-1 set /a lastnoblank=0 set /a curpos=1 set "str=Q!%1!" :StringLenLoop set SUBD=!str:

%curpos%,1! if "!SUBD!" == "" GoTo :formrez if NOT "!SUBD!" == " " ( if !firstnoblank! == -1 set firstnoblank=!curpos! set lastnoblank=!curpos! ) set /a curpos = !curpos!+1 GoTo :StringLenLoop :formrez set /a n1=!firstnoblank!-1 set /a n2=!lastnoblank!-!firstnoblank!+1 if !firstnoblank! == -1 (set "rez primer"> set "strr=" Call :ALLTRIM strr echo result ALLTRIM ^>%strr%^< . set "strrr= 22 33 " Call :ALLTRIM strrr echo result ALLTRIM ^>%strrr%^<

Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).

Новый раздел о средствах командной строки в рамках этого же проекта расположен здесь

Читайте также: