Я нашел решение на форуме OpenNET.ru, популярном русскоязычном -языковом ресурсе, посвященном -программному обеспечению и технологиям с открытым исходным кодом с 1996 года. сообщение на OpenNET предполагает, что Информация -ZIP, когда-то популярный набор инструментов для работы с ZIP-архивами на компьютерах под управлением MS -DOS, предполагал, что в MS -DOS существует только одна 8 -битная кодировка, а именно CP850, поэтому все имена файлов автоматически запустить преобразование CP850->CP1252
. CP1252, вероятно, был выбран как наиболее популярное приближение к кодировке набора символов ISO -8859 -1.
Таким образом, правильной командой find после извлечения архива, содержащего кириллические имена файлов, будет
find -mindepth 1 -exec sh -c 'mv "$1" "$(echo "$1" | iconv -f cp1252 -t cp850 | iconv -f cp866 )"' sh {} \;
Интересно, что можно найти предложения использовать не CP1252, а ISO -8859 -1. Это не похоже на тот случай, поскольку один из некоторых архивов, с которыми я столкнулся, преобразование iconv -f iso8859-1 -t cp850
не удалось, в то время как iconv -f cp1252 -t cp850
успешно преобразован.
Возврат к отдельным символам
Р о с К о с м о с
CP866: 90 AE E1 8A AE E1 AC AE E1
Теперь применение CP850 -> CP1252 приводит к C9 AB DF E8 AB DF BC AB DF
. Именно та последовательность, которую мы наблюдали.
Еще одна полезная команда:
unzip -l РосКосмос.zip | grep -aEv '^Archive:' | iconv -f iso8859-1 -t cp850 | iconv -f cp866
Чтобы получить список файлов из архива
Length Date Time Name
--------- ---------- ----- ----
0 2017-05-03 18:19 РосКосмос/ict_inf.pdf
--------- -------
0 1 file
Отфильтровывание строки, начинающейся с Archive:
, является защитой, позволяющей скрыть имя архива от преобразования.
Просто Bash не делает подобных вложенных подстановок, а zsh делает. Это похоже:
$ zsh -c 'a=abcdef; echo ${${a%ef}#ab}'
cd
$ bash -c 'a=abcdef; echo ${${a%ef}#ab}'
bash: ${${a%ef}#ab}: bad substitution
Обходной путь — использовать временную переменную:
$ tmp=($(echo "Hello World"))
$ printf "%s\n" "${tmp[@]}"
Hello
World
Заметьте это;
"$@"
или "${foo[@]}"
, так как в противном случае расширение приводит к разбиению слов -. Здесь это не имеет значения, так как слово -уже было разбито при присваивании, но в целом с массивами это имеет значение. echo
не очень хороший инструмент для просмотра результатов разбиения на слова, так как он объединяет все аргументы пробелами, так что вы не можете увидеть, есть ли пробелы в аргументах или echo
добавил их(echo "foo bar" doo
имеет тот же вывод, что и echo foo bar doo
).