Как преобразовать ссылку на вики-страницу в стиле Github в ссылку в стиле Markdown в скрипте Bash

#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