Это старая версия (1.14) ОболочкаShell.

Содержание

Оболочка shell

На этой странице будут собраны и разбиты на разделы практические приёмы использования оболочки (shell). Так как сама по себе оболочка является всего лишь тонким «клеем» для объединения программ и файлов в новые инструменты (через конвеер и перенаправление ввода-вывода), в этот раздел будут помещены ссылки на другие вики-страницы, где описаны приёмы работы с прочими классическими утилитами Unix.

Конвеер для работы с файлами

 $ find /etc -maxdepth 1 -type f | sort | ( echo cat ; cat ) | paste -s -d ' ' | sh >/tmp/all

Я бы отдал предпочтение tr вместо paste, вот так:

 $ find /etc -maxdepth 1 -type f | sort | { echo cat; cat; } | tr '\n' ' ' | sh >/tmp/all

Здесь запуск подоболочки (subshell) заменён на блок (в фигурных скобках), так как преследовалась цель объединить последовательно вывод утилит echo и cat на стандартный вывод. Для этой цели подоболочку запускать расточительно.

Здесь есть ещё одна потенциальная проблема, она связана с тем, что в именаx файлов могут встречаться любые символы, кроме нулевого байта (NUL) и слеша (/). В имени файла может присутствовать символ новой строки (NL), в то же время find печатает список файлов, отделяя этим символом имена друг от друга. Если в имени файла содержится символ новой строки, тогда вывод find не отличим от двух файлов, следующих подряд.

Если используются утилиты GNU, то следует воспользоваться расширением, которое заменяет символ разделителя в списке файлов, выводимом find:

 $ find /etc -maxdepth 1 -type f -print0 | sort -z | xargs -0 cat >/tmp/all

Здесь find выводит имена файлов разделяя их не символом новой строки, а нулевым байтом (NUL). В этом случае все утилиты конвеера должны понимать это соглашение, например, GNU sort и GNU xargs умеют обрабатывать списки файлов с таким разделителем. -- СиткаревГригорий


Фильтр sed

 $ echo "abcabc" | sed 's/\(.*\)\(\1\)/\1#\2/'
 abc#abc

В данном примере в регулярном выражении используется backreference. Регулярное выражение состоит из двух групп выделенных круглыми скобками. Первой группе соотвествует любой набор символов .*, во второй группе используется backreference \1 (отсыл на первое выражение), при чем эта группа выделит выражение идентичное первому. В выводе мы адресуем группы как \1 и \2 и разделяем их символом #.

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

sed имеет два буфера, первый -- pattern space -- это входной буфер, он заполняется автоматически при обработке входны данных (или принудительно смотри sed команды n, N), второй -- hold space -- буфер хранения, данные в этом буфер могут попасть только по специальной команде. Пользователь может копировать, добавлять данные из одного буфера в другой, обмениваться содержимым.

Команды могут объединяться в группы фигурными скобками:

 { action1; action2... }
а так же выполняться с условием, подобно AWK:
 condition { action }

Небольшой пример:

 $ sed -n 'H;${x;s/\n/ /g;p}' < /etc/passwd

H -- добавлять все входные строки из pattern space к данным в hold space, таким образом, мы скопим все входные строки в буфере хранения;

${ ... } -- $ означает последнюю строку, т.е все действия в фигурных скобках выполняться, только при обработке последней строки;

x -- обменять содержимое hold space с содержимым pattern space. Фактически все накопленные строки, перемещаются из hold в pattern буфер;

s/\n/ /g -- команда замены работает с pattern буфером, где теперь находятся все наши строки, заменяем символ переноса пробелом (g делаем это глобально, для всех \n);

p -- печатаем pattern буфер на экран. Все строки теперь объеднены в одну.

Слегка расширим предыдущий пример.

 $ sed -n '1h;1!H;${x;s/\n/ /g;p}' < /etc/passwd

1h -- первую строку копируем в hold буфер;

1!H -- все входные строки кроме первой добавляем в hold буфер, ! знак инвертирования условия, в нашем оно выполняется для всех строк кроме первой.

В остальном скрипт повторяет предыдущий.


Прокомментируйте, пожалуйста, что делают вышеперечисленные примеры вызова sed. -- СиткаревГригорий