Здравствуйте, товарищи. Ну чо, как оно?
Поехали еBash’ить. Сегодня разберём интересную задачку, которую я подкидываю на собесы. Задача со звёздочкой.
Суть задачи: нужно вывести строки в окно терминала и пронумеровать их, используя только один вызов sed. Аналогично выводу команды nl.
То есть должно получиться такое:
printf '%s\n' {a..d} | nl
1 a
2 b
3 c
4 d
Только это нужно сделать с помощью одного вызова sed.
Обычно те, кто берётся её решать, спустя какое-то время говорят: «Роман, иди нахуй, это сделать невозможно!»
Так говорят бедолаги, которым либо лень что-то делать, либо писька ещё не отросла. Всё возможно, было бы желание.
Короче, поехали решать. Давай попробуем сразу с sed несколько вариантов.
printf '%s\n' {a..d} | sed '='
printf '%s\n' {a..d} | sed -n 'p;='
printf '%s\n' {a..d} | sed -n '=;p'
Ну чёт да… ожидаемый результат совсем не ожидаемый.
Дело в том, что, когда sed встречает команду «=», он тут же пишет текущий номер строки с завершающим символом «\n» или «\0». То есть номер и строка разделены «\n» или «\0».
Поэтому в примерах по sed для решения этой задачи используют два вызова.
printf '%s\n' {a..d} | sed '=' | sed 'N;s/\n/ /'
Вот так всё корректно отработает, но задачу мы не решили, условия другие. Нам можно использовать лишь один sed.
Чо будем делать? Думать, ёпта!
Для начала надо посмотреть, а что мы имеем и на что можем повлиять.
Утилита sed пишет строки. Куда она их пишет? Вот и решение…
Вставляем в начало каждой строки управляющую последовательность, которая переместит курсор на предыдущую строку и установит его, например, в 3-й колонке.
printf '%s\n' {a..d} | sed '=;s/^/\x1b[1A\x1b[3G/'
Получаем ожидаемый результат:
1 a
2 b
3 c
4 d
Поздравляю! Задача решена с помощью всего лишь одного вызова sed.
Изучай. Всех с пятницей и хороших предстоящих выходных. Береги себя!








Комментарии