Практическое написание сценариев командной оболочки Bash/Bash подстановки: различия между версиями

Содержимое удалено Содержимое добавлено
Строка 827:
Весь фокус в том, что функция рекурсивно вызывается 5 раз (с учетом входа в рекурсию). На первом слое мы разрешаем крайнюю левую подстановку в шаблоне, т.е. крайняя левая <code>$1</code> заменяется словом <code>One</code>. Далее полученный после первой подстановки результат углубляется на новый уровень вместе с оставшимися аргументами, получаемыми через левый сдвиг, и операция повторяется. Операция будет повторяться до тех пор, пока в результате рекурсии не останется полностью разрешенный шаблон (если говорить точно, пока не останется последний аргумент).
 
В этой реализации мы вынуждены использовать мнимый аргумент (в этом примере он имеет значение <code>a</code>) для входа в рекурсию, так как нам не нужно, чтобы крайняя подстановка разрешилась на уровне первого вызова функции. Чтобы интерпретировать подстановку на нужном слое, мы используем символ экранирования нужное число раз. Обратите внимание, что нужное число слешей рассчитывается по-разному для двойных и одинарных кавычек. В случае двойных кавычек мы всегда должны держать в уме то, что слеш тоже интерпретируется внутри кавычек, поэтому после первого слоя каждый последующий слеш должен должен экранироваться дополнительно. Таким образом, число слешей для двойных кавычек рассчитывается как <math>2^n-1,\,\, n \in \overline {1,\infty}</math>, где <math>n</math> – номер слоя. В случае одинарных кавычек формула остается такой же, но слои начинают отсчитываться с нуля, а не с единицы.
 
Данная реализация имеет один большой недостаток: мы не можем использовать пробелы в самом шаблоне, поэтому пробельные символы в нем мы заменили символом нижнего подчеркивания. Дело в том, что пробелы в шаблоне будут приводить к разбиению шаблона на отдельные составляющие, в результате чего алгоритм выхода из рекурсии сработает слишком поздно. Чтобы исправить этот недостаток, функция должна знать, когда заканчиваются значения для шаблона и начинается сам шаблон. Для этих целей мы можем передавать в первом аргументе число подставляемых значений в шаблон. Тогда реализация будет такой: