Как разбить выражение по пробелам в bash?

Я нашел решение на форуме 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:, является защитой, позволяющей скрыть имя архива от преобразования.

2
10.08.2019, 00:15
1 ответ

Просто 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).
3
27.01.2020, 22:02

Теги

Похожие вопросы