Массовое преобразование cp1252 в utf-8 в Windows

Итак, я пытался преобразовать большое исходное дерево Java из cp1252 в UTF-8 в Windows, используя советы и триксы, которые я нашел в Интернете, в частности здесь. Проблема в том, что я на Windows; я не делаю ВБ; Значок Cygwin не использует переключатель -o.

Строка, которую я впервые попытался использовать:

find . -type f -print -exec iconv -f cp1252 -t utf-8 {} > {}.converted \; -exec mv {}.converted {} \;

Это создает файл {}.converted в рабочем каталоге, а второй -exec не работает по понятным причинам.

Помещение выражения iconv в кавычки:

find . -type f -print -exec 'iconv -f cp1252 -t utf-8 {} > {}.converted' \; -exec mv {}.converted {} \;

приводит к следующей ошибке:

find: `iconv -f cp1252 -t utf-8 ./java/dv/framework/activity/model/ActivitiesMediaViewImpl.java > ./java/dv/framework/activity/model/ActivitiesMediaViewImpl.java.converted': No such file or directory

хотя выполнение отдельных выражений вручную работает отлично.

Я экспериментировал со случайным цитированием, но ничего не работает, что я упускаю? Почему не получится..?

Заранее спасибо, Ларс


person Larsing    schedule 13.03.2012    source источник


Ответы (4)


Хорошо, еще раз отвечая на мой собственный вопрос (это начинает становиться плохой привычкой...)

Хотя в решении Нивека нет ничего плохого, перфекционист во мне хочет, чтобы выражение find -exec было правильным. Обертывание оператора iconv в sh -c '...' делает свое дело:

find . -type f -print -exec sh -c 'iconv -f cp1252 -t utf-8 {} > {}.converted' \; -exec mv {}.converted {} \;

Тем не менее, основной вопрос о том, почему возникает проблема с использованием перенаправления ввода-вывода в операторах find -exec, остается нерешенным...

person Larsing    schedule 14.03.2012

Я не очень часто использовал Cygwin, но есть «родная» версия Iconv для Windows, которую я использую все время. Вот выдержка из пакетного файла, который я использую для преобразования всех файлов в подкаталоге из кодировки HP-ROMAN8 в кодировку UTF-8, помещая результат «./temp» под оригиналы:

@set dir=оригинал

@set ICONV="C:\Program Files (x86)\iconv-1.9.2.win32\bin\iconv"

if EXIST .\%dir%\temp ( erase .\%dir%\temp*.* /Q @if ERRORLEVEL 1 (@echo Невозможно стереть все файлы из подкаталога "temp" @goto THE_END )) else ( mkdir .\%dir%\temp @if ERRORLEVEL 1 (@echo Невозможно создать подкаталог "temp" @goto THE_END ))

для %%f IN (./%dir%/*.xml) do ( %ICONV% -f HP-ROMAN8 -t UTF-8 "./%dir%/%%f" > "./%dir%/ temp/%%f", если ERRORLEVEL 1 (перейти к ICONV_ERROR))

person Murray McDonald    schedule 13.03.2012

Ошибка в первой попытке заключается в том, что оператор перенаправления '>' оценивается оболочкой до начала поиска.

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

В вашем рабочем решении первая команда, которую должен выполнить find, — это подоболочка, а параметры заключены в одинарные кавычки, поэтому они интерпретируются не внешней оболочкой, а подоболочкой.

person Mike11    schedule 03.01.2020

person    schedule
comment
Спасибо, это работает как задумано! Но знаете ли вы, почему выражение find-exec не работает? Это связано с перенаправлением вывода ..? - person Larsing; 14.03.2012
comment
Я не уверен, но -exec не предпочтителен. откуда-то я узнал, что -exec не может выполнять команды с длинными аргументами. Вместо этого я использую xargs. - person neevek; 14.03.2012