Развертывание строк

Каждый раз когда в командную строку Linux Shell вводится команда для выполнению, bash выполняет множество преобразований над текстом команды перед ее выполнением. Ранее мы сталкивались с подстановками файлов по шаблонам, но детально не разобрали как оно устроено. А оно является частью механизма развертывания. Например, когда в рабочей директории два файла test1.txt и test2.txt, мы можем выбрать их с помощью подстановки по шаблону «t*.txt». Например, если мы желаем их удалить, мы воспользуемся командой rm.

Программа rm в качестве аргументов ожидает имена файлов к удалению, а мы передали ей шаблон. На самом деле программа не видит наш шаблон. В процессе развертывания строки, наша команда была преобразована с перечислением всех файлов.

Программе rm, как и остальным, нет необходимости в поддержке шаблонов имен файлов, чтобы они работали. Выборка файлов происходит до выполнения программы. А программа выполняет лишь свой функционал Это позволяет экономить значительные ресурсы при разработке программ 🙂

Развертывание строк не ограничивается подстановкой имен файлов по шаблонам. Основной принцип в том, что при вводе какой-то инструкции с подстановками для выполнения, она преобразуется в другую, где все подстановки развернуты.

Чтобы увидеть конечный вид команды, которая выполняется после всех развертываний, нам понадобится команда, которая выводит все переданные аргументы. Воспользуемся командой echo. Она выводит все ее аргументы в стандартный вывод, который при необходимости можно перенаправить в файл.

При помощи команды echo и перенаправления вывода создадим два файла test1.txt и test2.txt с каким нибудь текстом.

С помощью echo можно записывать информацию в файл. Команда echo  считывает выводимые данные из аргументов команды, а не стандартного ввода, как мы это делали ранее с помощью программы cat. Аргументы любой команды являются частью вводимой инструкции, поэтому к ним применимо развертывание. Посмотрим как оно работает при помощи команды echo на подстановках имени файлов по шаблонам.

Каждая подстановка, в которой была произведена выборка файлов, замена последовательностью имен файлов. В последних двух примерах мы выполняли подстановку по шаблону «a*». Данному шаблону не соответствует ни одно имя файла в рабочей директории, потому подстановка развернута не была и осталась в неизменном виде.

Echo и подстановки файлов по шаблонам

Помимо подстановке имен файлов по шаблонам, существуют и иные развертывания строк.

Пользовательская директория

Нам уже известны специальные ярлыки пользовательских директорий. Они работают на этапе развертывания строк. Символ “~” (тильда) при развертывании заменяется на собственную домашнюю директорию. А если за ним следует имя учетной записи пользователя, тогда вся последовательность, начиная от символа «~» и заканчивая именем пользователя, заменяется на домашнюю директорию данного пользователя.

Арифметические операции

Linux Shell при развертывании вычисляет значения арифметических выражений. Командную строку можно использовать как калькулятор 🙂

Чтобы значение было вычислено, арифметическое выражение необходимо обернуть в двойные круглые скобки и поставить перед ними символ «$» (знак доллара).

Допускается использовать лишь целые числа. Вещественные числа (дроби) не поддерживаются 🙁 Пробелы в выражениях игнорируются, поэтому их можно использовать в качестве произвольных разделителей для удобства чтения. Выражения могут быть вложенными.

В данном примере во вложенным арифметическом выражении число 5 возводится в квадрат (2 степень), затем результат умножается на 3.

Для группировки вложенных выражений можно использовать круглые скобки. Тогда предыдущий пример будет короче и лучше читаем.

Возможно также целочисленное деление чисел и извлечение остатка. Попробуем разделить 5 жестких дисков на два компьютера, так чтобы каждый получил поровну.

Один диск остался в запасе 😉 Как мы заметили, развертывание выражений работает точно также как и развертывание подстановок имени файла по шаблону — происходит замена выражения на результат. Его можно использовать с любыми командами.

Попробуем записать список всех файлов в рабочей директории в файл, имя которого начинается со слова «test», после чего идет число равное результату умножения 25  на 132 (сколько будет? :)) и заканчивается строкой «.txt».

Развертывание последовательностей и комбинации

При помощи последовательностей можно создать множество различных комбинаций строк по заданному шаблону. Последовательность задается либо перечислением строк, либо интервалом целых чисел или символов.

Для развертывания последовательности, состоящей из интервала целых чисел или символов, в фигурных скобках указывают границы интервала, разделенные двумя точками («..»). Интервал может быть указан как в возрастающем порядке, так и в убывающем.

Если последовательность состоит из списка строк, то их разделяют запятыми и помещают в фигурные скобки.

Сами строки внутри последовательности тоже развертываются.

Последовательность можно окружить текстом, тогда при ее разворачивании у элементов последовательности тоже появится окружающий текст.

С учетом того, что к строкам внутри последовательности тоже применяется развертывание строк, возможно использование вложенных последовательностей.

К окружающему тексту тоже применяется развертывание строк.

А значит возможно составление сложных комбинаций их нескольких последовательностей.

Это очень удобно и позволяет сэкономить много времени. Ранее мы пытались создать дерево директорий для сортировки фотографий по датам, которое выглядело как photo/год/месяц/день. Тогда мы создали всего две директории (не считая родительских) photo/2014/01/10 и photo/2010/12/05. Сейчас мы создадим директории для всевозможных дат за 2013-2015 годы. Чтобы это выполнить нам вполне достаточно перечислить их имена (относительные пути), а родительские директории программа mkdir создаст автоматически. Но в году 365 дней, значит нужно перечислить все $((3*365)) 😉 директорий.

Попробуем решить задачу с помощью последовательностей. Первый шаблон, который приходит в голову «photo/{2013..2015}/{01..12}/{01..31}». Но тогда мы получим $((3*12*31)) директорий, что явно больше чем наши $((3*365)) дней в этих годах 🙂 Наверное, нужно учесть, разное количество дней в каждом месяце. Нам поможет вложенная последовательность. В итоге мы получим «photo/{2013..2015}/{{01,03,05,07,08,10,12}/{01..31},{04,06,09,11}/{01..30},02/{01..28}}». Перед тем, как что-то создавать, испытаем наш шаблон при помощи команды echo. Так как результат будет слишком длинным, перенаправим вывод в программу для чтения текста less и пролистаем там.

Начало сгенерированного списка директорий для дат при помощи последовательной и команды echo

Конец сгенерированного списка директорий для дат при помощи последовательной и команды echo

Выглядит как мы и ожидали. Значит теперь создадим все папки, заменив echo на mkdir с ключом -p.

Как видим, все прошло отлично. Столь сложная на первый взгляд задача была решена столько простой командой. Если кто-то не уверен, то может пробежать по всему созданному дереву директорий и проверить его вручную 🙂

Значения переменных

Переменные в Linux Shell позволяют записывать данные в области памяти, присваивая им имена, которые в дальнейшем можно использовать. При работе с командной строкой они не настолько полезны, как при разработке Shell скриптов, поэтому сейчас лишь поверхностно рассмотрим их.

Для развертывания значения переменной перед её именем ставится символ «$» (знак доллара). Например, мы желаем узнать значение переменной «USER». Выведем его с помощью команды echo.

Для вывода списка всех переменных окружения и их значений можно воспользоваться командой printenv.

Неустановленная (несуществующая) переменная при развертывании подменяется пустой строкой.

Чтобы задать значение переменной нужно указать имя переменной, после этого поставить символ «=» (знак равно) и указать значение переменной. Между именем переменной и символом «=» не должно быть пробелов. Зададим значение переменной «TEST».

Но, если мы попытаемся вывести список переменных при помощи команды printenv, то нашей переменной «TEST» там не будет.

Если быть более точным, команда printenv выводит только список переменных окружения, а мы задали локальную переменную «TEST». Подробно о внутреннем устройствое переменных и работе с ними я напишу в материалах программирования и разработки скриптов для Linux Shell. Если есть желание увидеть список всех переменных сейчас, можно самостоятельно научиться работать с командой set. Мы ведь помним где получить справку по незнакомой команде? 🙂

Подстановка команд

Мы уже знаем как перенаправить вывод команды в файл или прицепить к вводу другой команды. А еще его можно подставить в строку и передавать как аргументы другой команды. Для развертывания вывода команды, саму команду необходимо обернуть в круглые скобки и поставить перед ними символ “$” (знак доллара). Посмотрим как это работает.

Вместо знака доллара и скобок можно использовать символ «`» (обратная кавычка).

Данный функционал особо полезен при разработке Shell скриптов и его можно использовать совместно с переменными, записывая в них результат выполнения команд. Но об этом позже 🙂

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *