bash – вырезать подстроки в кавычках, разделенные пробелами, в массив

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

следующий пример:

string=" 'f o o' 'f oo' 'fo o' "
array=($string)
echo "${array[0]}"

выводит:

'f

в то время как ожидаемый вывод:

'f o o'

Единственное решение, которое я нашел, — это изменение разделителя на новую строку (вместо пробела):

IFS=$'\n'
string="'f o o' # 'f oo' # 'fo o' #"
array=($(echo "$string" | tr '#' '\n'))
echo "${array[0]}"

выводит:

'f o o'

что дает ожидаемый результат, однако для этого требуется установить пользовательский разделитель в строке, и это вызовет новый подпроцесс при каждом вызове. Мне было бы интересно увидеть лучшее решение, спасибо!

Ответ или решение

Чтобы решить задачу разбивки строки с разделёнными пробелами подстроками, заключенными в кавычки, в массив в Bash, необходимо учитывать особенность обработки пробелов внутри строк. Проблема заключается в том, что стандартный подход прерывает строку на пробелах, даже если они заключены в кавычки. Приведём решение, которое эффективно справится с этой задачей, не полагаясь на изменение разделителя и не вовлекая создание новых подпроцессов.

Проблема

Когда вы выполняете команду:

string=" 'f o o' 'f oo' 'fo o' "
array=($string)
echo "${array[0]}"

Первая позиция массива (${array[0]}) выводит 'f, так как пробелы внутри апострофов не признаются группирующими символами.

Решение

Для корректного разбора строки в массив, где группы символов могут содержать пробелы, нужно использовать eval вместе со специальными свойствами Bash-строк.

Кодовое решение

string=" 'f o o' 'f oo' 'fo o' "
eval "array=($string)"

echo "${array[0]}"  # Вывод: 'f o o'

Объяснение

  1. Использование eval:

    • eval выполняет строку как часть Bash-скрипта, обрабатывая все содержащиеся в ней специальные символы и обеспечивая правильный синтаксический разбор кавычек.
  2. Массив:

    • После обработки через eval, корректная группировка по кавычкам обеспечивается, и элементы массива сохраняют внутренние пробелы.

Преимущества предложенного решения

  • Отсутствие дополнительных процессов: в отличие от решения с tr и echo, здесь не создаётся дополнительные подпроцессы.
  • Чистота решения: нет необходимости менять переменные окружения или вводить искусственные разделители в строке.
  • Универсальность: такое решение подходит для различных строк, которые содержат кавычки и группы символов, разделённых пробелами.

Заключение

Использование eval в данных условиях позволяет сохранить оригинальность строки и автоматически корректно обрабатывать подстроки. Это делает решение не только более эффективным, но и изящным с точки зрения Bash-программирования. Таким образом, предложенное решение отвечает требованиям бизнес-аудитории, обеспечивая надежность и простоту исполнения в более широком спектре сценариев.

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

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