У меня есть файл уценки, который состоит из множества разных заголовков, я пишу сценарий CI, который изменяет один из разделов при каждом нажатии на репо. Мой README.md выглядит следующим образом:

README.md

# Title
....some text...
## Heading 1
...some text...

## Heading 2 
...some text....

## Structure
<pre>
┬  
 ├ first-dir
     ┬  first-sub-dir

 ├ second-dir
     ┬  second-sub-dir-1
     ├  second-sub-dir-2
</pre>

## Heading 3 
...some text....

Я хотел изменить раздел Structure выводом команды tree -d -L 2 -n с помощью sed. я пытался использовать

var=$(tree -d -L 2 -n)
sed -i -E "s/## Structure\n<pre>\n(.|\n)*?<\/pre>/## Structure\n<pre>\n ${var} \n<\/pre>/g" README.md

Но он не работал должным образом. Я читал о подстановке команд в sed, но не смог правильно понять. Любая помощь по этому поводу с sed или awk будет полезной.

0
Akash Tadwai 6 Июл 2021 в 07:39

1 ответ

Лучший ответ
awk '
/^<\/pre>$/             {flag=0}
/^## Structure$/        {print; getline; print
                        system("tree -d -L 2 -n")
                        flag=1}
!flag' <<<$(<file) >file

<<<$(<file) >file - своего рода пользовательский буфер (работает не во всех оболочках). Можно заменить временным файлом: file >tmp

Более сложный способ, привожу просто для примера:

sed -i '/^## Structure/!b
N;h
:1;N
/<\/pre>$/!b1
s/.*\n//
x;p
s/.*/tree -d -L 2 -n/e
G' file

/^## Structure/!b - Все строки, не соответствующие шаблону, игнорируются сценарием. И отображаются без изменений. Как только встречается шаблон, запускается следующий скрипт.
N - Добавить следующую строку ввода в пространство шаблонов (рабочий буфер). В итоге имеем - ## Structure\n<pre>
h — Копировать пространство шаблона для хранения пространства (запасной буфер).
:1 - Поставить отметку для прыжка.
N — добавить следующую строку. Попадаем в рабочий буфер - ## Structure\n<pre>\n┬
/<\/pre>$/!b1 - Если конец строки в рабочем буфере не соответствует шаблону, то возвращаемся к метке :1 и добавляем каждый цикл следующую строку, пока не будет добавлена ​​строка </pre>.< бр/> s/.*\n// - Затем мы удаляем все в рабочем буфере, кроме последней строки </pre>.
x - Меняем содержимое буферов между собой так, чтобы в рабочем буфере появилась строка - ## Structure\n<pre>. А в запасном буфере есть строчка - </pre>
p - Печать содержимого рабочего буфера ## Structure\n<pre>
s/.*/tree -d -L 2 -n/e - Заменяем содержимое буфера командой оболочки и выполняем ее.
G - Добавить содержимое </pre> запасного буфера к рабочему - добавить к выходной команде оболочки. Содержимое распечатывается, и задание возвращается к началу сценария. Следующая строка после </pre> считывается в рабочий буфер. А поскольку в шаблоне сопоставления файлов /^## Structure/!b больше нет строк, оставшиеся строки также отображаются без изменений, как первые.

1
nezabudka 7 Июл 2021 в 21:55
Здравствуйте, можете ли вы объяснить выражение sed, которое вы написали?
 – 
Akash Tadwai
7 Июл 2021 в 20:12