Программа   обрабатывает   многострочные   буферы   целиком    командами
редактирования,  слегка   похожие   на   команды   программы   sed.   Имеет
дополнительный  и  стек  буферов,  счётчик   и   поддерживает   динамически
сформированные регулярные выражения, позволяющие  искать  вложение  блоков.
Поиск и замены производятся и для нулевого  символа  \000  и  для  символов
перевода строки \n, но для этого во  входных  файлах  должно  не  оказаться
вплоть до двух неиспользованных байтов. Regex-ы имеют расширенный формат по
умолчанию и поддерживают нежадный синтасис, например, .*?. Имена файлов для
подгрузки файлов и выгрузки в файлы буферов в процессе работы  также  можно
формировать динамически.
Команды без аргументов могут быть склеены в одно слово и быть  префиксом
к комплексной команде поиска, сравнения и замен.
- #комментарии до конца строки;
Общий  формат  команд  замен,  возможно,  с   предварительным   поиском
регулярного выражения:
- (cmd[mod]*)+ [delim](arg[delim])+
Аргумент команд  после  необязательных  пробельных  символов  начинается
символом-разделителем,  который  может  быть  любым   непробельным,   кроме
обратного слеша \ и #. Выбор данного символа должен учитывать, что если  он
содержится в аргументах, то для экранирования его  обратным  слешем  он  не
должен совпадать с символами  специального  кодирования  (см.  ниже).  Если
пробелы перед аргументами отсутствуют, то символ-разделитель  будет  первым
не из  диапазона  команд  и  модификаторов:  ABCHIMNPQRWaceikmnosw.
Далее в документе используется /. Также далее и  выше  специальные  символы
()[]+*? соотвествуют значениям при составлении шаблонов regex,  так  символ
'?' указывает на необязательность модификатора.
- RI?o? /regex/ — команда поиска по regex. Дальнейшие
команды замен, склеенные без пробела выполняются при успешном поиске.
модификаторы команды R: 
- I — игнорировать регистр букв во входном буфере для
поиска regex;
- o —  повторять  при  успешном  поиске   комплексную
команду начиная с команды R  с  этой  опцией  до  конца  команды,  то  есть
пропуская команды предварительной инициализации до R.  Результирующий  флаг
успешности поиска  после  цикла  с  поиском  и  заменами  этой  комплексной
командой определяет значение флага самого первого поиска в этом цикле.
 
Команды замен буферов и счётчика:
- aH?  /replace/ —  добавить   replace   к   входному
буферу;
- cH?   /replace/ —   заменить   входной   буфер   на
replace;
- iH? /replace/ — вставить replace в начало  входного
буфера;
модификатор команд
- H — помещает в счётчик  количество  замен  перевода
регистра при использовании в replace кодов \l или \u
- AH?o?  /replace/ —  добавить   к   выходному   буферу
replace;
- CH?o? /replace/ — заменить выходной буфер на replace;
модификатор команд 
- o — печать буфер вывода, то есть выполняет команду
p
 
- PH?k?  /replace/ — заменить добавочный буфер
на replace.
модификатор команды P: 
- m /var_name/ —  заменить  добавочный буфер
на значение переменной окружения var_name;
- wH? /line/ — поместить выходной буфер в файл
с именем line;
модификатор команды w: 
- H — открывает указанный файл на дозапись
 
- n /line/ — поместить  в  счётчик  длину  полученной
строки в символах;
- B /line/ — поместить  в  счётчик  длину  полученной
строки в байтах;
- O  /line/ —  поместить  в  счётчик  значение   кода
первого символа line;
- N  /set_count/ —  команда   изменения   внутреннего
счётчика. Текстовая  строка  set_count  может  содержать  в  конце  простую
арифметическую операцию:  - +N — увеличить значение числа,
получившегося  после  текстовых  замен  на   число   N,   например,
N /\c+\c/ удвоит счётчик;
- -N — уменьшить на число N;
- *N — умножить на число N;
- /N — разделить на число N;
- &N — побитовое "и" с числом N;
- |N — побитовое "или" с числом N.
 
- M /cmp/ — команда сравнения счётчика и  возможно  с
установкой результата при кодировании с :флагом. cmp кодируется также как и
set_count в команде N. Команда выставляет флаги  для  перехода  по
условиям  t|F|G|g|L|l  и  меняет  флаг  успешности  поиска,   если
выполняется после успешного R  на  неуспешность,  если  счётчик  и
cmp неэквивалентны.
Дополнительно к кодированию  set_count  вместо  арифметической  операции
можно  использовать  следующие  код  флага  записи  в  счётчик   результата
сравнения: 
- :t — поместить в счётчик 1, если равно и  0  если  не  равно
cmp;
- :F — поместить в счётчик 0, если равно и  1  если  не  равно
cmp;
- :G — поместить в счётчик 1, если счётчик больше cmp и 0 если
меньше либо равно;
- :L — поместить в счётчик 1, если счётчик меньше cmp и 0 если
больше либо равно;
- :g — поместить в счётчик 1, если счётчик больше  либо  равно
cmp и 0 если меньше;
- :l — поместить в счётчик 1, если счётчик меньше  либо  равно
cmp и 0 если больше.
 
- V /line/ — вызвать  перекодировку  входного  буфера
через iconv, где в line указывается перекодирование по формату  /из:в/  или
/из/ или /:в/. Если одна из кодировок не указана, то  используется  текущая
кодировка из переменных окружения LC_ALL|LC_CTYPE|LANG.
Успешность перекодировки  зависит  от  возможности  замен  всех  входных
символов на выходные.  При  невозможности  замены  программа  записывает  в
счётчик  количество  замен  на  символ  '?'  для  проблемных   символов   и
осуществляется переход по метке при вызове команды  ?  label.  При
успешности  перекодировки  счётчик  не  меняется,   а   команда   v   label
осуществляет переход по метке; 
- e /line/ — вывести line в стандартный вывод  ошибок
stderr. Программа продолжит работу, но при завершении  код  возврата  будет
равен 1;
- W   /NN:line/ —   поместить   в   выходной    буфер
разрезанную с помощью \n по ширине NN line;
- T /line/ — поместить в выходной буфер текущее время
по формату strftime,  заданный  в  line.  Описание  формата  см.  в  man  3
strftime;
- Q /line/ — завершить выполнение программы  с  кодом
возварата указанном в line;
- sI?H? /regex/replace/ — Циклический поиск  regex  с
добавлением во внутренний накопитель начала текста до regex,  замену  regex
на replace, замену входного буфера на  остаток  после  regex  и  повторение
цикла. По окончании цикла производится формирование входного  буфера  путём
вставки перед остатком  заполненного  накопителя.  Флаг  успешности  поиска
после окончания цикла определяется, был ли успешным первый поиск с заменой.
Модификаторы команды s:
 
- I включает поиск без учёта регистра;
- H помещает в счётчик количество замен
перевода регистра при использовании в replace кодов \l или \u.
 
- z /XY/ — Поиск пары символов по принципу вложенных
скобок, так z /()/ найдет любое выражение (expr) с любым уровнем вложенных
скобок в основном буфере поиска. Буфер может начинаться с любых символов до
первого указаного в команде z, поиск будет успешным только при наличии
правильного соотношения скобок в первом выражении в буфере, а специальные
символы в следующих командах установятся на: \h - как начало буфера
до найденного выражения, \@ - найденное выражение и \z - остальной буфер.
Специальное  кодирование /regex/, /replace/, /set_count/, /line/,
/var_name/ и /cmp/:
- \i — поместить все данные из входного буфера (для команд
c и a — до помещения туда информации);
- \p — поместить данные из  буфера  вывода  (для  команд
C и A — до помещения туда информации);
- \g — поместить данные из дополнительного буфера (для команды
P — до помещения туда информации);
- \o — поместить имя обрабатываемого файла;
- \@ —  поместить  всю  найденную  информацию  согласно  regex
(аналог & в программе sed);
- \A до \Z — поместить подблок согласно (subregex) с указанным
номерами от первого до 26-го (аналог \1 ... \9 в sed);
- \h —  поместить  начало  буфера  до   найденной   информации
согласно regex;
- \z —  поместить  конец  буфера  после  найденной  информации
согласно regex;
- \l — перевести в нижний регистр (под)строку,  закодированную
следующим за этим кодом одним из всех вышеуказанных специальных кодов;
- \u — перевести в верхний регистр (под)строку, закодированную
следующим за этим кодом  одним  из  всех  вышеуказанных  специальных  кодов
(кроме \l);
- \y — неиспользованный байт во входном файле  и  в  указанных
/заменах/, можно применять как символ экранирования для работы с вложенными
структурами в тексте, см. приложенный пример math.bsed;
- \перевод_строки — игнорируется;
- \c — поместить значение счётчика;
- \0 \0[0-7] \0[0-7][0-7] \0[0-7][0-7] — значение байта
в восьмиричной кодировке;
- \a \b \e \f \n \r \t \v — значение байта по правилам
кодирования языков C и bash;
- \d — (только для команд s и R) сокращение от [[:digit:]];
- \\D — (только для команд s и R) сокращение от [^[:digit:]];
- \s — (только для команд s и R) сокращение от [[:space:]];
- \\S — (только для команд s и R) сокращение от [^[:space:]];
- \w — (только для команд s и R) сокращение от [[:alnum:]_];
- \\W — (только для команд s и R) сокращение от [^[:alnum:]_];
- \x[0-9A-Fa-f] \x[0-9A-Fa-f][0-9A-Fa-f] — значение байта
в шестнадцатеричной кодировке;
- \~ — поместить значение флага поиска и точного сравнения  со
счётчиком:
- 0 — поиск неуспешен или не равно для сравнения со счётчиком;
- 1 — если поиск успешен или сравнение показало равенство;
 
- \delim — если delim не вышеуказанные  коды,  то  вставляется
сам символ delim. 
Коды \@...\Z \h и \z —  результат  предыдущего  вызова  любой
команды R  и  разрешены  для  использования  только  до  изменения
входного буфера командами c|a|i|d|s|x|S|V|Y. Символ #  внутри  /#/
является обычным.
Пример из файла html_filter.bsed
по удалению html-комментариев:
DRoAcRc /<!--/\h/\z/-->/\z/ i /\p/
- D  очистит  выходной  буфер,  который  будет  использован  как
накопитель;
- Ro /<!--/ произведёт поиск начала комментариев,  дальнейшие
команды будут выполняться при успешном поиске в цикле;
- A /\h/ добавит  в  накопитель  начало  буфера  до  соотвествия
шаблона в предыдущей команде;
- c  /\z/  заменит  входной  буфер  остатком  после   найденного
шаблона;
- R /-->/ произведет поиск окончания комментария;
- c /\z/ заменит  входной  буфер  на  остаток  после  найденного
шаблона;
- i /\p/ по окончании  цикла  вставит  перед  остатком  входного
буфера заполненый накопитель.
Команды переходов и установки метки
- :  label —  установить  метку  для  изменения  хода
выполнения скрипта путём перехода  на  следующую  за  этой  меткой  команду
командами j|t|F|G|g|L|l. До имени метки  пробелы  не  обязательны,
имя метки заканчивается либо пробельным символом либо началом  комментариев
#. Имена меток должны быть уникальными. Зарезервированы имена, начинающиеся
с фигурных скобок { и };
- j label — безусловный переход на метку;
- t label — переход на метку, если  предыдущий  поиск
командой R  было  успешным  или  сравнение  счетчика  командой  M  показало
эквивалентность;
- F label — переход на метку, если  предыдущий  поиск
был неуспешным или сравнение счетчика показало неэквивалентность;
- v  label —  переход  на  метку,   если   предыдущее
перекодирование командой V было успешным, то есть  без  замен  символов  на
знаки '?';
- ?  label —  переход  на  метку,   если   предыдущее
перекодирование командой V было неуспешным, то есть c заменами символов  на
знаки '?';
- G|g  label —  переход  на  метку,  если  предыдущее
сравнение счетчика M /cmp/ показало, что счётчик больше cmp | либо
больше и равен;
- L|l  label —  переход  на  метку,  если  предыдущее
сравнение счетчика M /cmp/ показало, что счётчик меньше cmp | либо
меньше и равен.
Команды  j|(t|F|G|L|g|l|v|?)  завершают
работу скрипта с  текущим  файлом  (по  своему  условию),  если  метка  для
перехода в скрипте не определена командой : label.
- t|F|G|L|g|l|v|? { commands  } —  выполнить
команды  при выполнении условия, закодированного командой;
Команды  также  могут  содержать  свои   блоки
t|F|G|L|g|l|v|? {  commands  }.  После  завершения  блока
команд флаги успешности восстанавливаются в значение до  выполнения  команд
для возможности выполнить следующий блок с другим  условием,  например,
R /regex/ t { commands1 }  F  {  commands2  }
  где
команды  commands1  будут  выполнены,  если  regex  успешно   найдётся,   а
commands2 — если неуспешно. Коды \@...\Z  \h  и  \z  могут  быть
использованы только внутри t-блока до своих команд поиска внутри commands1.
Остальные коды отразят изменения  буферов,  произошедших  после  исполнения
команд в блоке.