Вопрос или проблема
У меня MacOS El Capitan – о bash это:
bash --version
... version: 3.2.57(1)-release...
...
Я осознал, что команда mapfile
недоступна
Через следующий пост:
Следующее решение работает отлично:
$ string='[Git status]-fn:-functionGitStatus'
$ mapfile -t array <<< "${string//-fn:-/$'\n'}"
$ echo "${array[@]}"
[Git status] functionGitStatus
$ echo "size: '${#array[@]}'"
2
$ for e in "${array[@]}"; do echo "'$e'"; done
'[Git status]'
'functionGitStatus'
Какая другая команда, доступная в bash 3.2.57, может помочь мне достичь того же подхода?
Используйте read -a
, конкретно:
bash-3.2> string='[Git status]-fn:-functionGitStatus'
bash-3.2> IFS=$'\n' read -rd '' -a array <<< "${string//-fn:-/$'\n'}"
bash-3.2> declare -p array
declare -a array='([0]="[Git status]" [1]="functionGitStatus")'
Как это работает:
- Опция
-a
дляread
указывает, что нужно читать в массив. -rd ''
указывает читать сырые значения (-r
) и читать до конца файла или нуля (-d ''
определяет NUL как разделитель строки).IFS=$'\n'
указывает использовать новую строку в качестве разделителя полей ввода — как раз то, что-a
будет использовать, чтобы понять, когда начинать новый элемент массива.
Другими словами, “прочитайте весь ввод, разделив его по новым строкам и поместив в массив array
“.
Ответ или решение
Вопрос о том, как эмулировать команду mapfile
в bash версии 3.2.57, встречается довольно часто среди пользователей более старых версий Unix-систем, таких как MacOS El Capitan. В этой версии bash команда mapfile
, которая используется для чтения строк в массив, отсутствует, что создает определенные сложности для пользователей, привыкших к более современным возможностям командной оболочки.
Теория:
В современных версиях bash команда mapfile
, также известная как readarray
, позволяет считывать данные из файла или стандартного ввода в массив. Эта функция становится особенно полезной при работе с текстовыми данными, когда нужно разделить файл на строки и сохранить их в массив для дальнейшего использования.
К сожалению, в более старых версиях, таких как bash 3.2.57, отсутствуют определенные конструкты, которые позволяли бы использовать mapfile
напрямую. Тем не менее, возможность работы с массивами все равно присутствует, и её можно использовать с помощью команды read
.
Пример:
Рассмотрим пример, в котором требуется разделить строку на компоненты, чтобы поместить их в массив. В более новых версиях bash это решается с помощью mapfile
, что мы видим в вашем примере. Однако в bash 3.2.57 мы можем воспользоваться комбинацией команды read
и переменной окружения IFS
(Internal Field Separator).
Вот что вам нужно сделать:
-
Замените строку: разделите вашу строку по необходимому символу или комбинации символов, заменив их на символ новой строки. Это облегчит дальнейшее чтение.
-
Используйте команду
read
: при помощиread
и переменнойIFS
(становой разделитель), читайте данные в массив. -
Обратите внимание на модификаторы: флаг
-a
позволяет записать данные в массив. Флаги-r
и-d ''
обеспечивают считывание до конца строки с сохранением всех текстовых данных.
Реализация:
Вот пример команды для bash 3.2.57, который продемонстрирует работу с массивом без использования mapfile
:
string='[Git status]-fn:-functionGitStatus'
IFS=$'\n' read -rd '' -a array <<< "${string//-fn:-/$'\n'}"
declare -p array
1. Замена строки
Фрагмент string//-fn:-/$'\n'
заменяет в строке -fn:-
на символ новой строки. Это разделяет вашу строку на две строки "[Git status]" и "functionGitStatus".
2. Использование команды read
Команда read
с модификаторами -a
, -r
, -d ''
выполняет такие действия:
-a
: Считывание в массив.-r
: Указываетread
не интерпретировать обратные косые черты как спецсимволы.-d ''
: Чтение продолжается до конца ввода, поскольку для завершения строки используетсяNUL
.
3. Использование переменной IFS
IFS устанавливается через $'\n'
, что делает символом разделения строки символ новой строки, помогая read
определить границы элементов массива.
Заключение:
Эмулирование mapfile
в старых версиях bash возможно и предоставляет почти все те же возможности, что и в современных системах. С использованием read
, IFS
, и возможностей замены строк вы можете достичь аналогичного результата. Это полезно не только для использования в операционных системах, ограниченных более старыми версиями bash, но и для понимания внутренней работы команд, что повышает вашу профессиональную компетентность и гибкость в обработке данных.
Таким образом, представленный метод не только решает прежние ограничения, но и стимулирует освоение основ работы с текстовыми данными в Unix-системах, обеспечивая плавную работу с более сложными скриптами и программами.