#arrays #bash #parsing
#массивы #bash #синтаксический анализ
Вопрос:
В скрипте bash я хотел бы преобразовать строку, содержащую переменную, разделенную символом «:», в массив.
Я вижу, что предлагаемый подход обычно
IFS=: read -r -a myarray <<< "$mystring"
Вместо этого я использовал команду, которая мне кажется более простой:
IFS=: myarray=($mystring)
Более того, на моем КОМПЬЮТЕРЕ это работает. Смотрите сценарий ниже
#!/bin/bash
mystring="var01:var02:var03:var04"
IFS=: myarray=($mystring)
echo "first variable is" "${myarray[0]}"
echo "second variable is" "${myarray[1]}"
echo "..."
вывод
first variable is var01
second variable is var02
...
Однако, поскольку я не нашел такого примера в Интернете, я не уверен, что это правильно…
В чем проблема использования этого в скрипте bash? Соответствует ли это стандарту?
Спасибо за ваш совет.
Ответ №1:
Хороший первый вопрос. У предложенной вами альтернативы есть проблемы. Сначала рассмотрим
$ str='a:%:*'
$ IFS=: read -r -a arr <<< "$str"
$ echo "${arr[@]}"
a % *
Результат является ожидаемым. Поскольку "$str"
он заключен в кавычки в herestring, он не подвергается расширению имени файла (так называемому глобированию), и все в порядке.
С другой стороны…
$ str='a:%:*'
$ IFS=: arr=($str)
$ echo "${arr[@]}"
a % 07-13:37:38.png 07-13:37:49.png Documents Downloads Pictures Music Xresources
Во втором случае $str
не заключен в кавычки и подвергается расширению имени файла, что означает *
, что он расширяется до всех файлов в моем текущем каталоге! Увы!
Ни одна из этих форм не совместима с POSIX, поскольку POSIX не определяет массивы в оболочках. Но оба они полностью допустимы в Bash, хотя, как показано, они делают разные вещи.
Ссылка в руководстве Bash: расширение имени файла.
Как вы уже заметили, вы можете использовать set -f
для отключения расширения имени файла. Это решило бы проблему IFS=: arr=($str)
, но некоторых может удивить. Если вы идете этим путем, установите его обратно с set f
помощью параметра сразу после этой строки, иначе настройка будет применена ко всей остальной части скрипта. Это увеличивает сложность решения, поэтому я рекомендую избегать этого, когда это возможно.
Комментарии:
1. Я прочитал в мануале Bash «После разделения слов, если только не была установлена опция -f». Итак, я полагаю, чтобы избежать этого, я должен сначала установить de option -f, но это увеличивает сложность решения. Я еще разберусь в этом, но я понимаю проблему