Markdown. Сдвиг уровня заголовков
Markdown. Сдвиг уровня заголовков
2026-01-02
·
8 мин. для прочтения
Markdown. Сдвиг уровня заголовков
Содержание
1 Сдвиг на один уровень вверх
- Регулярное выражение добавляет одну решётку
#к любому количеству существующих решёток в начале строки.
1.1 Регулярное выражение
^(#+)(.*)$
1.2 Замена
$1#$2
1.3 Как это работает
1.3.1 Регулярное выражение
^— начало строки (гарантирует, что мы меняем только заголовки, а не#внутри текста).(#+)— захватывающая группа:#— символ решётки;+— одно или более повторений (любая длина последовательности#в начале строки).
(.*)— захватывающая группа: весь остальной текст строки (содержание заголовка).$— конец строки.
1.3.2 Замена
$1— первая захваченная группа (исходные решётки);#— добавляем ещё одну решётку (повышаем уровень);$2— вторая захваченная группа (текст заголовка).
1.4 Пример
- Было:
# Заголовок 1
## Заголовок 2
### Заголовок 3
#### Заголовок 4
##### Заголовок 5
###### Заголовок 6
####### Заголовок 7 ← нестандартный, но валидный для некоторых парсеров
- Стало:
## Заголовок 1
### Заголовок 2
#### Заголовок 3
##### Заголовок 4
###### Заголовок 5
####### Заголовок 6
######## Заголовок 7
1.5 Замечания
H6 и выше:
- Стандарт Markdown поддерживает до H6 (
######). - Если у вас есть
#######(7 решёток), замена создаст########(8 решёток). Это невалидный синтаксис по спецификации, но некоторые парсеры (например, GitHub) его обрабатывают.
- Стандарт Markdown поддерживает до H6 (
Пробелы после
#:- Шаблон работает независимо от наличия пробелов:
#Заголовок→##Заголовок# Заголовок→## Заголовок
- Шаблон работает независимо от наличия пробелов:
Заголовки с замыкающими
#:Если используются формы вроде
# Заголовок #, сначала уберите замыкающие#отдельным поиском/заменой:^(#+)(.*?)\s*#*\s*$- Замена:
$1$2.
- Замена:
2 Сдвиг на один уровень вниз
- Для понижения уровня заголовков Markdown (H2 → H1, H3 → H2 и т. д.) нужно убрать одну решётку
#из начала строки. - При этом заголовки H1 (
# ...) должны остаться без изменений (иначе получится невалидный синтаксис).
2.1 Регулярное выражение
^(#+)(#)(.*)$
2.2 Замена
$1$3
2.3 Как это работает
2.3.1 Регулярное выражение
^— начало строки (гарантирует, что меняем только заголовки).(#+)— первая захватывающая группа:#+— одна или более решёток (захватывает все#в начале, кроме последней).(#)— вторая захватывающая группа:- ровно одна решётка
#(которую мы уберём).
- ровно одна решётка
(.*)— третья захватывающая группа:- весь остальной текст строки (содержание заголовка).
$— конец строки.
2.4 Замена
$1— первые решётки (без последней);$3— текст заголовка (пропускаем$2, т. к. именно её удаляем).
2.5 Пример
- Было:
# Заголовок 1 ← не изменится (H1)
## Заголовок 2 ← станет H1
### Заголовок 3 ← станет H2
#### Заголовок 4 ← станет H3
##### Заголовок 5 ← станет H4
###### Заголовок 6 ← станет H5
####### Заголовок 7 ← станет H6 (если парсер поддерживает)
- Стало:
# Заголовок 1
# Заголовок 2
## Заголовок 3
### Заголовок 4
#### Заголовок 5
##### Заголовок 6
###### Заголовок 7
2.6 Замечания
H1 остаётся без изменений:
- Шаблон
(#+)(#)требует минимум две решётки в начале строки. - Строки вида
# Заголовок(H1) не совпадут и не изменятся.
- Шаблон
Пробелы после
#:- Шаблон работает независимо от пробелов:
##Заголовок→#Заголовок## Заголовок→# Заголовок
- Шаблон работает независимо от пробелов:
Заголовки с замыкающими
#:- Если есть формы вроде
## Заголовок ##, сначала уберите замыкающие#отдельным поиском/заменой:^(#+)(.*?)\s*#*\s*$ - Замена:
$1$2.
- Если есть формы вроде
Ограничение до H6 (опционально):
- Если нужно не опускать ниже H6, используйте:
^(#{2,6})#(.*)$ - Замена:
$1$3. - Это понизит H2–H6, но оставит H1 и H7+ без изменений.
- Если нужно не опускать ниже H6, используйте:
3 Регулярные выражения для Emacs
- Регулярные выражения в нотации Emacs.
- Ключевые особенности:
- Экранирование групп:
\(и\)вместо(и); - Экранирование квантификаторов:
\+вместо+,\{1,5\}вместо{1,5}; - Обратные ссылки:
\1,\2вместо$1,$2.
- Экранирование групп:
3.1 Сдвиг заголовков вверх (H1 → H2, H2 → H3 и т. д.) (c ограничением по уровню)
- Регулярное выражение (Emacs)
^\(#\{1,5\}\)\(.*\)$
- Замена (Emacs)
\1#\2
3.1.1 Пояснение
^— начало строки;\(#\{1,5\}\)— захватываем от 1 до 5 решёток;\(.*\)— захватываем остальную часть строки;$— конец строки;\1#\2— вставляем первую группу, добавляем#, вставляем вторую группу.
3.2 Сдвиг заголовков вверх (без ограничения по уровню)
- Регулярное выражение (Emacs)
^\(#+\)\(.*\)$
- Замена (Emacs)
\1#\2
3.2.1 Пояснение
\(#+\)— захватываем одну или более решёток;- остальное — аналогично предыдущему.
3.3 Сдвиг заголовков вниз (H2 → H1, H3 → H2 и т. д.; H1 не меняется)
- Регулярное выражение (Emacs):
^\(#+\)#\(.*\)$
- Замена (Emacs):
\1\2
3.3.1 Пояснение
\(#+\)— захватываем все решётки, кроме последней;#— одна решётка, которую удаляем;\(.*\)— остальная часть строки;\1\2— вставляем первую и третью группы (вторую пропускаем).
3.4 Сдвиг заголовков вниз с ограничением до H6 (H2–H6 понижаем, H1 и H7+ не трогаем)
- Регулярное выражение (Emacs):
^\(#\{2,6\}\)#\(.*\)$
- Замена (Emacs):
\1\2
3.4.1 Пояснение
\(#\{2,6\}\)— захватываем от 2 до 6 решёток (т. е. уровни H2–H6);#— удаляемая решётка;\(.*\)— текст заголовка;\1\2— склеиваем первую и третью группы.
3.5 Как применять в Emacs
- Откройте файл в Emacs.
- Нажмите
M-x replace-regexp(илиC-M-%дляquery-replace-regexp). - Введите регулярное выражение и замену в формате выше.
- Нажмите
Enter— Emacs предложит поочерёдно подтвердить замены.
3.6 Примечания
- Экранирование: в Emacs
+,{,},(и)требуют обратного слеша\. - Группы:
\(и\)создают группы,\1,\2ссылаются на них. - Пробелы и табуляции: если в заголовках есть пробелы после
#, выражения работают корректно (пробелы входят в.*). - Замыкающие
#: если есть формы вроде# Заголовок #, сначала уберите замыкающие#отдельным поиском:- Regexp:
^\(#+\)\(.*?\)\s*#*\s*$ - Replace:
\1\2
- Regexp:
4 Регулярные выражения для sed
4.1 Синтаксис sed для замены по регулярным выражениям
Общий формат:
sed -i 's/шаблон/замена/g' файл.md-i— редактирование файла «на месте» (in‑place);s/— команда замены (substitute);/шаблон/замена/— шаблон поиска и строка замены;g— глобальная замена (все совпадения в строке; для заголовков обычно не нужно, т. к. одно совпадение на строку);'...'— кавычки, экранирующие спецсимволы для оболочки.
В BSD‑версии
sedтребуется суффикс после-i(например,-i ''). В GNUsed(Linux) можно-iбез суффикса.
4.2 Сдвиг заголовков вверх (H1 → H2, H2 → H3 и т. д.)
4.2.1 С ограничением до H5 (H6 не меняется)
- Команда:
sed -i '' 's/^\(#\{1,5\}\)\(.*\)$/\1#\2/g' файл.md
Пояснение
^— начало строки;\(#\{1,5\}\)— захватывающая группа: от 1 до 5 решёток#;\(.*\)— захватывающая группа: весь остальной текст строки;$— конец строки;\1#\2— подстановка: первая группа + одна решётка + вторая группа.
Пример
- Было:
# Заголовок→ Стало:## Заголовок - Было:
##### Заголовок→ Стало:###### Заголовок ###### Заголовок(H6) → не меняется.
- Было:
4.2.2 Без ограничения по уровню (любой H → H+1)
- Команда:
sed -E -i 's/^(#+)(.*)$/\1#\2/g' файл.md
- Пояснение:
(#+)захватывает одну или более решёток (не ограничиваясь 5).
Пример
####### Заголовок(7 решёток) →######## Заголовок(8 решёток).
4.3 Сдвиг заголовков вниз (H2 → H1, H3 → H2 и т. д.; H1 не меняется)
4.3.1 Без ограничений (любой H≥2 → H−1)
- Команда:
sed -E -i '' 's/^(#+)#(.*)$/\1\2/g' файл.md
Пояснение
(#+)— захватываем все решётки, кроме последней;#— одна решётка, которую удаляем;(.*)— текст заголовка;\1\2— склеиваем первую и третью группы (вторая — удаляемая решётка).
Пример
## Заголовок→# Заголовок### Заголовок→## Заголовок# Заголовок(H1) → не меняется (требуется минимум две решётки).
4.3.2 С ограничением до H6 (H2–H6 → H−1, H1 и H7+ не меняются)
Команда
sed -E -i 's/^(#{2,6})#(.*)$/\1\2/g' файл.md- Отличие:
(#{2,6})захватывает от 2 до 6 решёток.
- Отличие:
Пример
## Заголовок(H2) →# Заголовок(H1);###### Заголовок(H6) →##### Заголовок(H5);####### Заголовок(H7) → не меняется.
4.4 Итоговые команды
4.4.1 Сдвиг вверх (без ограничений)
sed -E -i 's/^(#+)(.*)$/\1#\2/g' файл.md
4.4.2 Сдвиг вниз (без ограничений)
sed -E -i 's/^(#+)#(.*)$/\1\2/g' файл.md
4.4.3 Сдвиг вверх (до H5)
sed -E -i '' 's/^(#{1,5})(.*)$/\1#\2/g' файл.md
4.4.4 Сдвиг вниз (до H6)
sed -E -i 's/^(#{2,6})#(.*)$/\1\2/g' файл.md
4.4.5 Примечания
Пробелы после
#:Все приведённые команды работают независимо от наличия пробелов после решёток:
##Заголовок→#Заголовок;## Заголовок→# Заголовок.
Замыкающие
#(форма# Заголовок #):- Если такие есть, сначала уберите их отдельной командой:
sed -E -i 's/^(#+)(.*?)\s*#*\s*$/\1\2/g' файл.md - Это удалит все
#в конце строки после пробела.
- Если такие есть, сначала уберите их отдельной командой:
Тестирование перед применением:
- Чтобы увидеть результат без изменения файла, опустите
-i:sed -E 's/^(#+)(.*)$/\1#\2/g' файл.md - Вывод отобразится в терминале.
- Чтобы увидеть результат без изменения файла, опустите
Authors
Профессор кафедры теории вероятностей и кибербезопасности
Мои научные интересы включают физику, администрирование Unix и сетей.