Вопрос или проблема
следующий пример:
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'
Объяснение
-
Использование
eval
:eval
выполняет строку как часть Bash-скрипта, обрабатывая все содержащиеся в ней специальные символы и обеспечивая правильный синтаксический разбор кавычек.
-
Массив:
- После обработки через
eval
, корректная группировка по кавычкам обеспечивается, и элементы массива сохраняют внутренние пробелы.
- После обработки через
Преимущества предложенного решения
- Отсутствие дополнительных процессов: в отличие от решения с
tr
иecho
, здесь не создаётся дополнительные подпроцессы. - Чистота решения: нет необходимости менять переменные окружения или вводить искусственные разделители в строке.
- Универсальность: такое решение подходит для различных строк, которые содержат кавычки и группы символов, разделённых пробелами.
Заключение
Использование eval
в данных условиях позволяет сохранить оригинальность строки и автоматически корректно обрабатывать подстроки. Это делает решение не только более эффективным, но и изящным с точки зрения Bash-программирования. Таким образом, предложенное решение отвечает требованиям бизнес-аудитории, обеспечивая надежность и простоту исполнения в более широком спектре сценариев.