Найти тему
Блокнот математика

Рубрика "Секреты Вим". Как перевернуть карту

Привет, коллеги. Небольшая заметка о задаче только что решенной и притом нетривиальной, не из учебника.

Карта глубин моря задана в текстовом файле. И она довольно большая. Формируется по данным, и вот оказалось, что она отзеркалена: строки идут в обратном порядке. А строки снабжены номерами, чтобы удобнее было. И перед нами две задачи: перевернуть строки, обратив их порядок, и заменить номера, так как после обращения порядка строк их номера пойдут в порядке убывания.

Фрагмент карты, цветом выделена суша (там нули).
Фрагмент карты, цветом выделена суша (там нули).

Номера строк с ведущими нулями, то есть 001, 002, и так далее.

Можно обратить порядок строк так:

:%g/\S/m0

Выражение \S (класс непробельных символов) совпадет на всех непустых строках, а других у нас и нет. Они будут по одной переноситься (команда m) по одной под нулевую строку, то есть выше первой. Первая отправится выше первой, то есть останется на месте; вторая окажется выше неё, ещё выше третья, и так далее.

Но можно проще: отсортировать, полагаясь на алфавитную упорядоченность трехзначных номеров строк:

:%sort!

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

А как заменить номера? Есть несколько способов.

Я выбрал такой:

:%s/^\d\+/\=printf("%03d", line('.'))/

Используем замену с вычисляемым выражением подстановки. В этом выражении вызываем функцию printf(), которая преобразует число в формат с ведущими нулями. Число же - номер текущей строки, который извлекает функция line.

Можно было другое выражение взять, например, line('$')-submatch(0)+1 Тогда из номера последней строки вычитался бы тот номер, который сейчас совпал.

Можно было записать макрос, в котором прибавлять к регистру единицу и потом вставлять его в нужной позиции:

ставим курсор на начало первой строки;
:let @a = 0
qq:let @a = @a + 1<CR>
cw <C-R>a<ESC>j0q
500@q

Здесь <> означает, что надо нажимать указанное сочетание или клавишу.

Что мы делаем? Мы обнуляем регистр a, включаем (q) запись макроса в регистре q, увеличиваем регистр. Удаляем слово (cw) с переходом в режим вставки. Вставляем регистр через <C-R>. Выходим из режима вставки. Спускаемся на строку (j) и переходим (на всякий случай) в ее начало (0). Завершаем запись (q).

Повторяем макрос сколько надо раз.

Вот так вот легко, в одну строчку, решается довольно сложная задача.

Удачи, коллеги!

Научно-популярные каналы на Дзене: путеводитель
Новости популярной науки12 марта 2022