Эквивалент команды ‘mapfile’ для bash 3.2.57

Вопрос или проблема

У меня 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).

Вот что вам нужно сделать:

  1. Замените строку: разделите вашу строку по необходимому символу или комбинации символов, заменив их на символ новой строки. Это облегчит дальнейшее чтение.

  2. Используйте команду read: при помощи read и переменной IFS (становой разделитель), читайте данные в массив.

  3. Обратите внимание на модификаторы: флаг -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-системах, обеспечивая плавную работу с более сложными скриптами и программами.

Оцените материал
Добавить комментарий

Капча загружается...