#bash #github #sed #markdown #wiki
Вопрос:
первый вопрос для меня по переполнению стека.
Я пытаюсь написать сценарий Bash для преобразования вики-ссылок Github, созданных для других внутренних вики-страниц Github, в обычные ссылки в стиле уценки.
Строки вики-ссылок на Github выглядят следующим образом:
[[An example of another page]]
Я хочу преобразовать его так, чтобы он выглядел следующим образом:
[An example of another page](An-example-of-another-page.htm)
В документах есть неизвестное количество этих ссылок, и я не знаю их содержания.
В настоящее время я играю с однострочными решениями sed для других проблем, таких как эта:
https://askubuntu.com/questions/1283471/inserting-text-to-existing-text-within-brackets
… абсолютно безрезультатно. Я даже не знаю, с чего начать.
Спасибо.
Комментарии:
1. РЕДАКТИРОВАТЬ: Чтобы уточнить, мне нужно оставить обычные ссылки с уценкой, которые являются частью той же строки (например
[link 1](link1.htm)
), что и они. Итак:[link 1](link1.htm) and [[link 2]]
становится[link 1](link1.htm) and [link 2](link-2.htm)
Ответ №1:
Вы можете попробовать это sed
$ sed -E 's/[(.[^]]*)]/1/g;s/[(.[^]]*)]/amp;(1)/g;:jump s/(([^ )]*)[ ]/1-/;tjump' input_file
[An example of another page](An-example-of-another-page)
s/[(.[^]]*)]/1/g
— Снимите скобки []
s/[(.[^]]*)]/amp;(1)/g
— Дублируйте содержимое в скобках []
, верните совпадение amp;
, затем обработайте совпадение и добавьте скобки (1)
:jump s/(([^ )]*)[ ]/1-/;tjump
— Создайте метку jump
, сопоставьте пустые места внутри совпадения, если оно находится в круглых скобках, и замените на -
Комментарии:
1. Спасибо. Это полезное начало. Проблема с вашим решением заключается в том, что оно удаляет ранее существовавшие ссылки на уценку. Поэтому, если у вас есть
[link 1](link1.html) and [[link ]]
в одном потоке, он правильно изменяет последнюю ссылку на уценку, но удаляет форматирование из первого:link 1(link1.htm)
я уточнил это в исходном вопросе.
Ответ №2:
Вы можете использовать внутреннюю поддержку регулярных выражений bash для поиска и замены экземпляров вики, с которыми связаны [[text]]
[text](text.htm)
. Шаблон, который вы хотите использовать, это [[([^]]*)]]
[
и]
— избегает левых и правых квадратных скобок, чтобы они не интерпретировались как мета-символы, позволяющие сопоставлять классы символов([^]]*)
захватывает весь текст внутри двойных скобок до первой правой квадратной скобки
Оттуда вы можете оценить это регулярное выражение и использовать $BASH_REMATCH
массив для извлечения текста и управления им. Вам нужно будет выполнить это несколько раз, чтобы сопоставить все экземпляры в строке, а затем заменить строку встроенной /
с помощью операторов //
и.
Вот пример сценария:
#!/usr/bin/env bash
wiki_string="Now, this is [[a story]] all about how
My life [[got flipped-turned upside down]]
And I'd [[like to take a minute]]
Just [[sit]] right there
I'll [[tell you]] how I [[became the prince]] of a town called Bel-Air"
printf 'Original: %sn' "$wiki_string"
# find each instance of [[text]] and capture the text inside
# the square brackets
# if successful, BASH_REMATCH will contain the matched text and the
# captured value inside the parentheses
while [[ "$wiki_string" =~ [[([^]]*)]] ]]; do
# escape the [ and ] characters so we can replace [[text]]
# with our modified value
replace_text="${BASH_REMATCH[0]}"
replace_text="${replace_text/[[/\[\[}"
replace_text="${replace_text/]]/\]\]}"
# Get the matched value inside the brackets
link_text="${BASH_REMATCH[1]}"
# store another copy of the text with the spaces replaced
# with dashes and appending .htm
link_target="${link_text// /-}.htm"
# Finally, replace the matched [[text]] with [text](text.htm)
wiki_string="${wiki_string//$replace_text/[$link_text]($link_target)}"
done
printf 'nUpdated: %sn' "$wiki_string"
Комментарии:
1. Спасибо за ответ. Это очень полезно. На данный момент я надеюсь
sed
, что ответ Хэтлесса может быть получен, поскольку он лучше соответствует краткому сценарию, который у меня сейчас есть. Однако я вернусь к вашему и изучу его, так как там есть много такого, о чем я не знал, что можно сделать.
Ответ №3:
Спасибо Хэтлессу за ответ, который я адаптировал. Приведенный ниже фрагмент преобразует ссылки в стиле Github в ссылки в стиле Markdown без двух проблем, с которыми столкнулось решение HatLess. В частности, это не нарушает ранее существовавшие ссылки в стиле уценки и не заменяет пробелы дефисами в скобках, если только они не являются частью ссылки.
sed -E 's/[[(.[^]]*)]]/amp;(support-1.htm)/g;:jump s/(]([^ )]*)[ ]/1-/;tjump;s/[[/[/g;s/]](/](/g' | pandoc -t html