Неболь­шая кол­лек­ция sed-скриптов.


Содер­жа­ние:

Неце­ле­вое исполь­зо­ва­ние поточ­ного редак­тора.

На дан­ной стра­нице пред­став­лен крат­кий анно­ти­ро­ван­ный спи­сок неко­то­рых непрак­тич­ных сце­на­риев для широко извест­ного поточ­ного редак­тора sed. В работе этой ути­литы основ­ное место зани­мает команда s/<шаблон>/<замещающий_текст>/ (вме­сто сим­вола / может исполь­зо­ваться и дру­гой раз­де­ли­тель), ищу­щая и заме­ня­ю­щая фраг­мент тек­ста, удо­вле­тво­ря­ю­щий неко­то­рому регу­ляр­ному выражению-шаблону.

Эта команда, могу­щая пока­заться далёкой по своей функ­ци­о­наль­но­сти от обес­пе­че­ния Тьюринг-полноты вход­ного языка sed, вме­сте с мет­ками и коман­дами пере­хода (услов­ного и безуслов­ного) всё же делает дан­ный редак­тор вычислительно-универсальным. Фак­ти­че­ски, он может рас­смат­ри­ваться в каче­стве реа­ли­за­ции нор­маль­ных алго­риф­мов Мар­кова (хотя это и не обще­при­ня­тое мне­ние), а пол­нота по-Тьюрингу обу­слав­ли­вает саму воз­мож­ность всех про­изо­шед­ших с sed при­клю­че­ний [с его нестан­дарт­ным исполь­зо­ва­нием].

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

Сложно, а быть может уже и вовсе невоз­можно ска­зать, какие ещё необыч­ные сце­на­рии писа­лись за всю исто­рию суще­ство­ва­ния этого редак­тора, исполь­зо­вав­ше­гося с начала/середины семи­де­ся­тых годов про­шлого века; так что остаётся лишь про­дол­жать неспеш­ные поиски ана­ло­гич­ных арте­фак­тов и, конечно, писать свои.

Итак, моя учет­ная запись на GitHub содер­жит сле­ду­ю­щие репо­зи­то­рии со скрип­тами для sed:

ocr-in-sed

Этот скрипт напи­сан под впе­чат­ле­нием от одно­строч­ной C-программы неко­его Эрика Коп­чин­ского (Eryk Kopczynski), напи­сан­ной для небезыз­вест­ного кон­курса ioccc за 2004 год и выпол­ня­ю­щей опти­че­ское рас­по­зна­ва­ние тек­ста находя эйле­рову харак­те­ри­стику его «три­ан­гу­ля­ции» (насколько вообще можно гово­рить о три­ан­гу­ля­ции для кар­тинки в стиле ASCII-арт).

Да, меня тоже сна­чала сбила с толку воз­мож­ность рас­по­зна­ва­ния на основе именно этого топо­ло­ги­че­ского инва­ри­анта, оче­видно име­ю­щего оди­на­ко­вые зна­че­ния вообще для всех пла­нар­ных гра­фов; поэтому инте­ре­су­ю­щихся пока пере­ад­ре­сую на ста­тью (S.B.Gray, Local Properties of Binary Images in Two Dimensions, 1971), пред­по­ло­жи­тельно явля­ю­щу­юся осно­вой для про­граммы Коп­чин­ского. По-сути, авторы расчи­ты­вают инва­ри­ант, рав­ный раз­но­сти между коли­че­ством связ­ных обла­стей и коли­че­ством дырок, но расчи­ты­вают его под­счи­ты­вая раз­лич­ные чисто локаль­ные кон­фи­гу­ра­ции пик­се­лей в -окне, про­бе­гая им по всему изоб­ра­же­нию (в ста­тье этот свер­точ­ный под­ход рас­про­стра­нен и на -окна, но у Коп­чин­ского при­ме­нено малень­кое окно).

Увы, осо­бая про­стота этой логики сильно огра­ни­чи­вает функ­ци­о­наль­ность осно­ван­ной на ней про­граммы рас­поз­но­ва­ния сим­во­лов… И кроме целых из, ска­жем так, не очень боль­шого про­ме­жутка эта OCR-программа ничего рас­по­знать тол­ком не может.

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

drawing-in-sed

Про­стой гра­фи­че­ский редак­тор, выпол­ня­ю­щий команды со стан­дарт­ного ввода и реа­ли­зу­ю­щий неко­то­рое подмножество/версию чере­па­шьей гра­фики и систем Лин­ден­май­ера. Сго­дится для рисо­ва­ния неко­то­рых гео­мет­ри­че­ских фигур, сим­во­лов, фрак­та­лов. Не самое оче­вид­ное при­ме­не­ние sed, не так ли?

computus-in-sed

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

langton-ant-in-sed

Симу­ля­ция извест­ного авто­мата «мура­вей Ланг­тона», инте­рес­ного, среди про­чего, своей Тьюринг-полнотой и инте­рес­ной откры­той про­бле­мой, свя­зан­ной с аттрак­то­рами («до­ро­га» с пери­о­дом 104 шага) этой дина­ми­че­ской системы для всех конеч­ных началь­ных кон­фи­гу­ра­ций.

elementary-ca-in-sed

Эле­мен­тар­ные одно­мер­ные конеч­ные авто­маты по-Вольфраму. Доста­точно полез­ная воз­мож­ность для sed, поз­во­ля­ю­щая созда­вать узоры, гене­ри­ро­вать псев­до­слу­чай­ные числа, моде­ли­ро­вать неко­то­рые физи­че­ские про­цессы.

life-in-sed

Игра «жиз­нь» Кон­вея, теперь и на sed.

music-in-sed

Пиа­нино на sed! Кто же не делал что-то вроде cat /dev/urandom > /dev/audio или sudo cat /dev/mem > /dev/audio? Редак­тор sed вполне может при­няв со стан­дарт­ного ввода нот­ную запись, син­те­зи­ро­вать после­до­ва­тель­ность сим­во­лов, кото­рая будучи отправ­лен­ной в oss-устройство /dev/audio (или его ана­лог), при­во­дит к про­иг­ры­ва­нию соот­вет­ству­ю­щей мело­дии через зву­ко­вую карту. Всё очень про­сто. :)

Пово­дом для напи­са­ния этого скрипта яви­лось сооб­ще­ние Kyle Keen об этом спо­собе гене­ра­ции звука. Но там был при­ме­нен пол­но­цен­ный язык про­грам­ми­ро­ва­ния awk, поз­во­лив­ший легко полу­чить более каче­ствен­ный чем у меня звук за счет исполь­зо­ва­ния тре­уголь­ной формы сиг­нала. Так появи­лась музы­каль­ная программа-синтезатор на гораздо более огра­ни­чен­ном sed, именно в силу огра­ни­чен­но­сти и пред­став­ля­ю­щем боль­ший спор­тив­ный инте­рес.

maze-in-sed

В попытке понять напи­сан­ную на sed одним [пред­по­ло­жи­тельно Син­га­пур­ским] хаке­ром про­грамму поиска выхода из лаби­ринта я напи­сал свою вер­сию, вклю­чив в поставку [пока не пол­но­стью рабо­то­спо­соб­ный] ком­пле­мен­тар­ный гене­ра­тор лаби­рин­тов (есте­ственно тоже на sed).

sieve-in-sed

Решето Эра­то­сфена на sed. Кроме соб­ственно решета, реа­ли­зо­ван­ного в sieve.sed, в репо­зи­то­рии можно найти скрипт factor.sed, раз­ла­га­ю­щий дан­ное число на его про­стые дели­тели. А для демон­стра­ции при­ме­не­ния про­стых чисел (и в соот­вет­ствии с эзо­те­ри­че­ской направ­лен­но­стью подоб­ных раз­вле­че­ний с редак­то­ром sed) позже были добав­лены скрипты anagram.sed и collatz.sed, – для детек­ти­ро­ва­ния ана­грамм, и для реа­ли­за­ции дина­ми­че­ской системы из гипо­тезы (гипо­тезы Кол­латца), соот­вет­ственно.

Позже была напи­сана реа­ли­за­ция решета Эйлера, вычер­ки­ва­ю­щего каж­дое состав­ное число только один раз (см. euler-sieve.sed в том же репо­зи­то­рии). Правда, как потом выяс­ни­лось, этот код не имеет вообще ника­ких пре­иму­ществ перед обыч­ным реше­том Эра­то­сфена из-за слиш­ком доро­гой опе­ра­ции умно­же­ния на sed или, по край­ней мере, из-за выбран­ного спо­соба осу­ществ­ле­ния умно­же­ния.

Объ­яс­не­ние работы дан­ных скрип­тов содер­жится в отдель­ном сооб­ще­нии этого днев­ника.

superpermutations-in-sed

Гене­ра­ция [вообще говоря, не явля­ю­щихся мини­маль­ными] супер­пе­ре­ста­но­вок.

cw-in-sed

Этот скрипт при­ни­мает на вход тек­сто­вое сооб­ще­ние и гене­ри­рует тональ­ный теле­граф­ный сиг­нал (код Морзе), про­иг­ры­ва­е­мый зву­ко­вой кар­той ком­пью­тера по прин­ципу, опи­сан­ному выше в раз­деле о син­те­за­торе мело­дий.

r2d2-in-sed

Син­те­за­тор «ре­чи» робота r2d2 из все­лен­ной «Звёзд­ных Войн» Д.Лукаса. При­ме­нен тот же прин­цип гене­ра­ции тек­сто­вого потока, озву­чи­ва­е­мого пере­на­прав­ле­нием в /dev/audio. В отли­чии от программы-пианино или от гене­ра­тора «мор­зян­ки», здесь кроме чистых нот (на самом деле всего-лишь пря­мо­уголь­ного сиг­нала вме­сто сину­со­иды) име­ется воз­мож­ность созда­ния белого шума, а так­же воз­мож­ность слу­чай­ного выбора нот.

Инте­ресно, можно ли научить r2d2 гово­рить [по-человечески]? Пора вне­сти син­те­за­тор речи в TODO-список. :)

infix-compiler-in-sed

Даже будучи тек­сто­вым редак­то­ром, sed не предо­став­ляет удоб­ных инстру­мен­тов для раз­бора (син­так­си­че­ского ана­лиза) контекстно-свободных грам­ма­тик. Наи­бо­лее про­стой метод раз­бора, а именно рекурсивно-нисходящий ана­лиз, сло­жен в реа­ли­за­ции на sed из-за отсут­ствия адек­ват­ной под­держки рекур­сии. Однако в тео­рии ничто не мешает напи­сать рекурсивно-нисходящий пар­сер, и даже ком­пи­ля­тор, для какого-нибудь про­стого языка, напри­мер для ариф­ме­ти­че­ских фор­мул (с обыч­ной инфикс­ной нота­цией).

Кон­кретно этот про­ект явля­ется малень­ким (и страшно неэф­фек­тив­ным) ком­пи­ля­то­ром фор­мул, при­ни­ма­ю­щим ариф­ме­ти­че­ское выра­же­ние (ска­жем, (1+2)*3) и про­ду­ци­ру­ю­щим насто­я­щий машин­ный код ([пока] только для x86-архитектуры и для 32 бит­ного Linux в каче­стве ОС). На дан­ный момент, мой скрипт не умеет гене­ри­ро­вать пол­но­цен­ный испол­ня­е­мый файл (хотя это в прин­ципе и воз­можно), поэтому для добав­ле­ния всех необ­хо­ди­мых заго­лов­ков я реко­мен­дую вос­поль­зо­ваться Perl-скриптом m2elf.pl.

banner-in-sed

Упро­щен­ный ана­лог ути­лит типа banner/sysvbanner или figlet. Для дан­ной строки печа­тает её «ASCII-art» вари­ант (c боль­шими сим­во­лами), про­сто скле­и­вая соот­вет­ству­ю­щие её зна­кам фраг­менты тек­ста из спе­ци­ально под­го­тов­лен­ного «шриф­та». Под­дер­жи­ва­ется авто­ма­ти­че­ская кор­рек­ция меж­бук­вен­ных интер­ва­лов, т.е. авто­кер­нинг (с воз­мож­но­стью наблю­де­ния за бес­по­лез­ной, но забав­ной ани­ма­цией этого про­цесса).

quine-kleene-generator

Гене­ра­тор (неэф­фек­тив­ных) квай­нов для sed. Правда, сам гене­ра­тор пред­став­ляет собой набор как sed-скрип­тов, так и скрип­тов обо­лочки. Для гене­ра­ции квай­нов исполь­зу­ется дока­за­тель­ство вто­рой рекур­сив­ной тео­ремы Клини о непо­движ­ных точ­ках частично-рекурсивных функ­ций. N.B., квайны полу­ча­ются очень боль­шими по раз­меру, но гене­ра­тор всё-равно ока­зался поле­зен в моих неболь­ших экспериментах/упражнениях по тео­рии вычис­ли­мо­сти.

Подроб­но­сти можно найти в серии сооб­ще­ний «За­ни­ма­тель­ное квай­но­вод­ство».


Мини­ре­по­зи­то­рии

Кроме этого на http://gist.github.com/Circiter/ хра­нятся сле­ду­ю­щие «ми­ни­ре­по­зи­то­рии» (gists):

Nota bene, я почти все­гда пишу на диа­лекте GNU sed, что, увы, создаёт про­блемы с исполь­зо­ва­нием моих sed-скриптов на вся­ких там Mac’ах, BSD’ях и этих ваших Android’ах. Воз­мо­жен ли кон­вер­тер (может быть даже напи­сан­ный, о ужас, на самом sed) из GNU в Posix и смогло ли бы это решить про­блему пор­та­бель­но­сти?

Post scriptum. Мно­гие из моих sed-сценариев, — ровно как и насто­я­щий спи­сок, — носят чисто развлекательно-экспериментальный харак­тер и пер­ма­нентно нахо­дятся в режиме написания/дописывания; функ­ци­о­наль­ность может менятся кар­ди­нально без пред­ва­ри­тель­ных уве­дом­ле­ний и раци­о­наль­ных обос­но­ва­ний.


Скрипты дру­гих авто­ров.

Выше была опи­сана задача транс­ля­ции между диа­лек­тами sed. Бли­жай­шие по смыслу най­ден­ные мною про­екты – sedcheck.sed за автор­ством Laurent Vogel, про­ве­ря­ю­щий скрипты на Posix-совместимость; и транс­ля­тор sed-bin от Quentin L’Hours, кон­вер­ти­ру­ю­щий sed в C (при­ме­ча­тельно, что оба про­екта сами явля­ются sed-скриптами).

Нако­нец, транс­ля­тор https://github.com/shinh/elvm поз­во­ляет пре­об­ра­зо­вать C-код снова в sed. И хотя сам он и не напи­сан на sed, но может оттранс­ли­ро­вать самого себя с C на sed. Поэтому, можно счи­тать, что sed-bin и elvm сов­местно могли бы исполь­зо­ваться для «нор­ма­ли­за­ции» sed-скриптов.

Про­дол­жим обзор мира sed.

На стра­ни­цах http://sed.sourceforge.net и http://sed.sourceforge.net/grabbag (автор: Paolo Bonzini) можно найти неплохую кол­лек­цию sed-скриптов раз­ной сте­пени полез­но­сти. Сто­ить отме­тить неко­то­рые из пред­став­лен­ных там вещей:

Так же на про­сто­рах интер­нета были най­дены:

М.И.Никитин
г.Алматы, апрель, 2020


метки-категории: эзо­те­рика, про­грам­ми­ро­ва­ние, sed

[ЭЦП (SHA-256, RSA)] (ключ)