Компьютерный форум 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=252100)

VedunO 22-01-2013 18:10 2072550

Замена в имени файлов кириллицы на латиницу
 
Подскажите, как можно заменить русские буквы на латинские во всех файлах данной папки?
Я имею в виду похожие русские и латинские буквы, например: "а" (рус) на "a" латинскую и т.д.
Имена файлов различные, расширения тоже. Необходимо для последующей заливки на сервер,
а из-за кириллицы в именах файлов возникают проблемы...

Anonymоus 22-01-2013 21:27 2072660

VedunO, для этого вам понадобится создать вот такой вот скрипт и разместить его рядом с тем, откуда он будет вызываться, либо же добавить в path:

func_translit.cmd
Код:

@Echo Off
:: Inquisitor, 2013
SetLocal EnableDelayedExpansion

:: Первый аргумент служит в качестве входящих данных.
Set Data=%~1

:: Проверяем на то, передан ли аргумент и заменяем пробелы на нижнее
:: подчеркивание.
If Defined Data (Set Data=!Data: =_!) Else (Exit /B 1)

:: Посимвольная обработка и поиск соответствия символам кириллицы
:: в соответствии с таблицей транслитерации. Если символ не указан в
:: таблице - он остается неизменным.
Set Result=
:Translit
Set Char=!Data:~,1!
For /F "tokens=2 delims==" %%A In ('Find "::#%Char%=" "%~dpnx0"') Do (Set Char=%%A)
Set Result=!Result!!Char!
If Not "!Data:~1!"=="" (
        Set Data=!Data:~1!
        GoTo Translit
) Else (
        Echo !Result!
)
Exit /B 0

:: Таблица транслитерации
::#a=a
::#б=b
::#в=v
::#г=g
::#д=d
::#е=e
::#ё=yo
::#ж=zh
::#з=z
::#и=i
::#й=i
::#к=k
::#л=l
::#м=m
::#н=n
::#о=o
::#п=p
::#р=r
::#с=s
::#т=t
::#у=u
::#ф=f
::#х=kh
::#ц=c
::#ч=ch
::#ш=sh
::#щ=sh
::#ъ=.
::#ы=y
::#ь=.
::#э=e
::#ю=yu
::#я=ya
::#А=A
::#Б=B
::#В=V
::#Г=G
::#Д=D
::#Е=E
::#Ё=Yo
::#Ж=Zh
::#З=Z
::#И=I
::#Й=I
::#К=K
::#Л=L
::#М=M
::#Н=N
::#О=O
::#П=P
::#Р=R
::#С=S
::#Т=T
::#У=U
::#Ф=F
::#Х=Kh
::#Ц=C
::#Ч=Ch
::#Ш=Sh
::#Щ=Sh
::#Ъ=.
::#Ы=Y
::#Ь=.
::#Э=E
::#Ю=Yu
::#Я=Ya

Имейте в виду, что скрипт должен быть сохранён в кодировке 866, это важно. Все пробелы заменяются на нижние подчеркивания, а кириллица - транслитерируется в латиницу (ГОСТ 7.79-2000, система Б) согласно таблице. Используется много вызовов Find, поэтому производительность скрипта оставляет желать лучшего.

Образец вызова скрипта:
Код:

@Echo Off
Set Filename=Новый текстовый документ.txt
Echo Old filename = %Filename%
For /F "delims=" %%A In ('func_translit "%Filename%"') Do (Set Filename=%%A)
Echo New filename = %Filename%
Pause


gora 22-01-2013 23:28 2072743

Цитата:

Цитата Anonymоus
Используется много вызовов Find, поэтому производительность скрипта оставляет желать лучшего. »

Ускорил:
Код:

@Echo Off
:: Inquisitor, 2013
SetLocal EnableDelayedExpansion

:: Первый аргумент служит в качестве входящих данных.
Set Data=%~1

:: Проверяем на то, передан ли аргумент и заменяем пробелы на нижнее
:: подчеркивание.

If Defined Data (Set Data=!Data: =_!) Else (Exit /B 1)
For %%I In (a_a б_b в_v г_g д_d е_e ё_yo ж_zh з_z и_i й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sh ъ_. ы_y ь_. э_e ю_yu я_ya А_A Б_B В_V Г_G Д_D Е_E Ё_Yo Ж_Zh З_Z И_I Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sh Ъ_. Ы_Y Ь_. Э_E Ю_Yu Я_Y) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do Set Data=!Data:%%A=%%B!
Echo !Data!
Exit /B 0


Iska 22-01-2013 23:46 2072759

gora, оригинально!

Anonymоus 23-01-2013 00:22 2072779

gora, браво, превосходно! Мне такой вариант решения даже в голову не пришел.

VedunO 23-01-2013 09:19 2072904

Anonymоus, gora,
Благодарю выручили!!!

gora 23-01-2013 09:24 2072909

Цитата:

Цитата VedunO
Благодарю выручили!!! »

Рано. Там не все так гладко как оказалось... :( Надо еще поковырять и исправить.

VedunO 23-01-2013 09:47 2072922

рано обрадовался :(
и попутно вопрос: как можно это применить к списку файлов? (обработать все файлы в указанной папке)

gora 23-01-2013 10:55 2072963

Код:

@Echo Off
:: Кодировка файла Кириллица DOS (866)
SetLocal EnableDelayedExpansion
:: Путь к обрабатываемой папке
Set Folder=e:\Temp\3 3

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

:: Список замен
:: Set preset=а_a б_b в_v г_g д_d е_e ё_yo ж_zh з_z и_i й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sh ъ_. ы_y ь_. э_e ю_yu я_ya А_A Б_B В_V Г_G Д_D Е_E Ё_Yo Ж_Zh З_Z И_I Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sh Ъ_. Ы_Y Ь_. Э_E Ю_Yu Я_Ya

Set preset=а_a б_b в_v г_g д_d е_e ё_yo ж_zh з_z и_i й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sh ъ_. ы_y ь_. э_e ю_yu я_ya

:: После проверки слово ECHO удалить
For /F "tokens=* delims=" %%A In ('Dir /S /B /A:-D "%folder%"') Do (
        Call :_translit "%%~nA"
        Echo Ren "%%A" "!Data!%%~xA"
)
Pause
Exit


:_translit
Set Data=%~1
Set Data=%Data: =_%
For %%I In (%preset%) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do Set Data=!Data:%%A=%%B!
GoTo :EOF


zion87 23-01-2013 12:10 2073021

gora, попытался с двумя файлами:

Текстовый документ.txt
и
Документ Microsoft Office Word.docx

на выходе:

vекbvовlй_докgменv.txt
и
Докgменv_Microsoft_Office_Word.docx

gora 23-01-2013 12:20 2073034

zion87, у меня так:



Может кодировка при копировании с форума бьется? Вот файл
Какая у Вас система, русская? И что выдает команда ChCp в консоли?

zion87 23-01-2013 13:45 2073099

Да с этим файлом все на УРА!!!

gora 23-01-2013 16:01 2073192

Код:

@Echo Off
:: Кодировка файла Кириллица DOS (866)
SetLocal EnableDelayedExpansion
:: Путь к обрабатываемой папке
Set Folder=e:\Temp\1

:: Список замен
Set preset=а_a б_b в_v г_g д_d е_e ё_yo ж_zh з_z и_i й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sh ъ_. ы_y ь_. э_e ю_yu я_ya А_A Б_B В_V Г_G Д_D Е_E Ё_Yo Ж_Zh З_Z И_I Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sh Ъ_. Ы_Y Ь_. Э_E Ю_Yu Я_Ya

:: После проверки слово ECHO удалить
For /F "tokens=* delims=" %%A In ('Dir /S /B /A:-D "%folder%"') Do (
        Call :_translit "%%~nA"
        Echo Ren "%%A" "!Result!%%~xA"
)
Pause
Exit


:_translit
Set Data=%~1
Set Data=%Data: =_%
Set Result=
:_loop

Set Char=%Data:~,1%
For %%I In (%preset%) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do If %Char%==%%A Set Char=%%B
Set Result=%Result%%Char%
Set Data=%Data:~1%
If Defined Data GoTo _loop
GoTo :EOF


kiripanda 23-01-2013 17:31 2073267

Плагин для Total Commander http://wincmd.ru/search.php?s=Translit_wdx

nsky 24-01-2013 18:04 2074138

Цитата:

Цитата gora
Код: »

1 - пару Я_Ya в конце таблицы preset упустил;

2 - если в предпоследнем If использовать при сравнении кавычки, то отпадает необходимость замены пробелов на символ подчеркивания.

Код:

@Echo Off
:: Кодировка файла Кириллица DOS (866)
SetLocal EnableDelayedExpansion
:: Путь к обрабатываемой папке
Set Folder=e:\Temp\1

:: Список замен
Set preset=^
 а_a б_b в_v г_g д_d е_e ё_yo ж_zh з_z и_i й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sh ъ_. ы_y ь_. э_e ю_yu я_ya^
 А_A Б_B В_V Г_G Д_D Е_E Ё_Yo Ж_Zh З_Z И_I Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sh Ъ_. Ы_Y Ь_. Э_E Ю_Yu Я_Ya

:: После проверки слово ECHO удалить
For /F "tokens=* delims=" %%A In ('Dir /S /B /A:-D "%folder%"') Do (
        Call :_translit "%%~nA"
        Echo Ren "%%A" "!Result!%%~xA"
)
Pause
Exit

:_translit
Set Data=%~1
Set Result=
:_loop
Set Char=%Data:~,1%
For %%I In (%preset%) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do If "%Char%"=="%%A" Set Char=%%B
Set Result=%Result%%Char%
Set Data=%Data:~1%
If Defined Data GoTo _loop
GoTo :EOF

Кстати, какой тег следует использовать для подсветки синтаксиса cmd? Я не нашел среди "тегов форума"...

gora 24-01-2013 21:32 2074267

nsky
1 Спасибо, поправил
2 Учитывая, что:
Цитата:

Цитата VedunO
Необходимо для последующей заливки на сервер »

решил, что без пробельные имена будут удобнее
3 http://forum.oszone.net/thread-206940.html

nsky 25-01-2013 10:49 2074608

gora,
Ему решать...
А как насчет этого:
Цитата:

Цитата nsky
Кстати, какой тег следует использовать для подсветки синтаксиса cmd? Я не нашел среди "тегов форума"... »


gora 25-01-2013 10:50 2074611

Цитата:

Цитата nsky
А как насчет этого: »

Цитата:

Цитата gora


kiripanda 25-01-2013 19:58 2074958


Цитата:

А как насчет этого:


velmyshanovnyi 20-01-2019 00:40 2853366

небольшой апдейт для универсальности ))

просьба обновить по указанным ссылкам

HTML код:

  rem ====================
  rem // http://forum.oszone.net/thread-252100-2.html
  rem // http://www.cyberforum.ru/cmd-bat/thread671391-page2.html#post4256934
  rem ====================
  rem Список замен
  rem UPDATE from:
  rem https://en.wikipedia.org/wiki/Cyrillic_script
  rem https://uk.wikipedia.org/wiki/Кирилиця
  rem https://ru.wikipedia.org/wiki/Кириллица
  rem ====================
  Set preset=а_a б_b в_v г_g ґ_g ѓ_gj д_d ђ_dj е_e є_ie ё_yo ж_zh з_z и_i і_i ї_ji й_i к_k л_l љ_lj м_m н_n њ_nj о_o п_p р_r с_s т_t ќ_c ћ_c у_u ф_f х_kh ц_c ч_ch џ_dz ш_sh щ_shch ъ_. ы_y ь_' э_e ю_yu я_ia А_A Б_B В_V Г_G Ґ_G Ѓ_Gj Д_D Ђ_Dj Е_E Є_Ye Ё_Yo Ж_Zh З_Z И_I І_I Ї_Ji Й_I К_K Л_L Љ_Lj М_M Н_N Њ_Nj О_O П_P Р_R С_S Т_T Ќ_C Ћ_C У_U Ф_F Х_Kh Ц_C Ч_Ch Џ_Dz Ш_Sh Щ_Shch Ъ_. Ы_Y Ь_' Э_E Ю_Yu Я_Ya
  rem ====================


delite 01-06-2024 03:56 3027781

Цитата:

Цитата velmyshanovnyi
небольшой апдейт для универсальности )) »

Дак а как же апдейтить, если необходима кодировка 866? Там эти спецсимволы при сохранении просто превращаются в вопрос и всё.

У меня есть папки с копирайтом ©️ в названии, их правильно видит обычный dir, но результаты через цикл for уже просто с буквой "c", такие папки не переименовываются, и ничего с этим не сделать, я так понимаю, как и с другими спецсимволами вне кодировки 866.
Также невозможно переименовать папки с восклицательным знаком, потому что ! превращается в Result
Также невозможно добавить в список замены запятуюб

Немного расширил ваш скрипт под свои хотелки, положу под спойлеры

Транслитерация имён папок

Код:

@Echo Off
:: Кодировка файла Кириллица DOS (866)
SetLocal EnableDelayedExpansion
:: Путь к обрабатываемой папке
cls
echo.

if "%~1"=="" (goto END_NOPARAM) else (goto CHECK)
:CHECK
if not exist %~1 (goto END_NOTEXIST) else (goto START)
:START
 
set "Folder=%1"
echo Обрабатываем папку %Folder%...
echo Будут затронуты только папки, не файлы.
echo.
pause

set /a count = 0
set /a count_renamed = 0
set /a count_skipped = 0

:: Список замен
Set preset=^
 а_a б_b в_v г_g д_d е_e є_ie ё_yo ж_zh з_z и_i ї_ji й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sch ъ_ ы_y ь_ э_e ю_yu я_ya №_# ^
 А_A Б_B В_V Г_G Д_D Е_E Є_Ye Ё_Yo Ж_Zh З_Z И_I Ї_Ji Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sch Ъ_ Ы_Y Ь_ Э_E Ю_Yu Я_Ya

For /F "tokens=* delims=" %%A In ('Dir /ad/b/s "%folder%"^| sort/r') Do (
        set /a count += 1
        Call :_translit "%%~nxA"

        if "%%~nxA"=="!Result!" (
            set /a count_skipped += 1
            echo [-][!count!] Пропускаю папку "%%~nxA", путь "%%~fA"
            echo [-] Пропускаю папку "%%~nxA", путь "%%~fA">>%~dp0folders.skipped.txt
        ) else (
            set /a count_renamed += 1
            echo [+][!count!] Переименовываю папку "%%~nxA" в "!Result!"
            echo [+] Переименовываю папку "%%~nxA" в "!Result!">>%~dp0folders.renamed.txt
            Ren "%%A" "!Result!"
        )

)
echo.
echo ====================================
echo Переименовано папок: %count_renamed%
echo Пропущено папок: %count_skipped%
Pause
Exit

:_translit
Set Data=%~1
Set Result=
:_loop
Set Char=%Data:~,1%
For %%I In (%preset%) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do If "%Char%"=="%%A" Set Char=%%B
Set Result=%Result%%Char%
Set Data=%Data:~1%
If Defined Data GoTo _loop
GoTo :EOF

:END_NOPARAM
echo Не указана папка или путь к папке в качестве параметра.
pause & exit

:END_NOTEXIST
echo Папка %~1 не существует.
pause & exit


Транслитерация имён файлов

Код:

@Echo Off
:: Кодировка файла Кириллица DOS (866)
SetLocal EnableDelayedExpansion
:: Путь к обрабатываемой папке
cls
echo.

if "%~1"=="" (goto END_NOPARAM) else (goto CHECK)
:CHECK
if not exist %~1 (goto END_NOTEXIST) else (goto START)
:START
 
set "Folder=%1"
echo Обрабатываем папку %Folder%...
echo Будут затронуты только файлы, не файлы.
echo Конечное расширение файла не будет затронуто. Отчёт.24года.смета.пример === otchet.24goda.smeta.пример
echo.
pause

set /a count = 0
set /a count_renamed = 0
set /a count_skipped = 0

:: Список замен
Set preset=^
 а_a б_b в_v г_g д_d е_e є_ie ё_yo ж_zh з_z и_i ї_ji й_i к_k л_l м_m н_n о_o п_p р_r с_s т_t у_u ф_f х_kh ц_c ч_ch ш_sh щ_sch ъ_ ы_y ь_ э_e ю_yu я_ya №_# ^
 А_A Б_B В_V Г_G Д_D Е_E Є_Ye Ё_Yo Ж_Zh З_Z И_I Ї_Ji Й_I К_K Л_L М_M Н_N О_O П_P Р_R С_S Т_T У_U Ф_F Х_Kh Ц_C Ч_Ch Ш_Sh Щ_Sch Ъ_ Ы_Y Ь_ Э_E Ю_Yu Я_Ya

For /F "tokens=* delims=" %%A In ('Dir /S /B /A:-D "%folder%"') Do (
        set /a count += 1
        Call :_translit "%%~nA"

        if "%%~nA"=="!Result!" (
            set /a count_skipped += 1
            echo [-][!count!] Пропускаю файл "%%~nxA", путь "%%~fA"
            echo [-] Пропускаю файл "%%~nxA", путь "%%~fA">>%~dp0files.skipped.txt
        ) else (
            set /a count_renamed += 1
            echo [+][!count!] Переименовываю файл "%%~nxA" в "!Result!%%~xA"
            echo [+] Переименовываю файл "%%~nxA" в "!Result!%%~xA">>%~dp0files.renamed.txt
            Ren "%%A" "!Result!%%~xA"
        )

)
echo.
echo ====================================
echo Переименовано файлов: %count_renamed%
echo Пропущено файлов: %count_skipped%

Pause
Exit

:_translit
Set Data=%~1
Set Result=
:_loop
Set Char=%Data:~,1%
For %%I In (%preset%) Do For /F "tokens=1,2 delims=_" %%A In ("%%I") Do If "%Char%"=="%%A" Set Char=%%B
Set Result=%Result%%Char%
Set Data=%Data:~1%
If Defined Data GoTo _loop
GoTo :EOF

:END_NOPARAM
echo Не указана папка или путь к папке в качестве параметра.
pause & exit

:END_NOTEXIST
echo Папка %~1 не существует.
pause & exit


Опиум 26-06-2024 15:45 3028506

Цитата:

Цитата Anonymоus
Все пробелы заменяются на нижние подчеркивания »

узнать бы имена тех чертей из MS, которые решили в свое время разрешить пробел в именах файлов/папок...


Время: 21:59.

Время: 21:59.
© OSzone.net 2001-