さまざまなヘッダーを含むMarkdownファイルがあり、リポジトリにプッシュするたびにセクションの1つを変更するCIスクリプトを作成しています。私のREADME.mdは次のようになります。
読む.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
sedを使用してコマンド出力の一部を変更したいと思います。tree -d -L 2 -n
使ってみよう
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
。
答え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