前の行がパターンと一致しない場合は、sedを使用して複数の行の間にテキストを追加します。

前の行がパターンと一致しない場合は、sedを使用して複数の行の間にテキストを追加します。

私は<dl>定義リストの周りにタグを追加するためにsedを使用するのが難しいです。たぶんこれを行うより簡単な方法があるかもしれません(知りたい)。

ファイル内で次を含む行を検索したいが、<dt>前の行に次が含まれている場合にのみ一致します。いいえ<dt>またはを含みます<dd>。一致するものが見つかったらを挿入します<dl>

これまでに試したこと(まったく一致しません):

sed '/^((?!<dt>).)*$/ {
    N
    /<dt>/ {
        s/<dt>/<dl><dt>/
    } 
}' file

ファイルもあります。

# TODO #

 * Set up mail transfer agent
 * Reconfigure timezone

```bash
dpkg-reconfigure tzdata
```

# Hardware #
  <dt>RAM</dt>
  <dd>2GB</dd>

# Partitions #

<dt>`/dev/sda1`</dt>
<dd>/boot</dd>
<dt>`/dev/sda2`</dt>
<dd>/</dd>

このすべての目的は、新しいwikiエンジンに移植するためにmoinmoin Wikiマークアップをマークダウンに変換するパーサーを作成することです。現在の定義のリストは、次の規則に従って開発されています。

sed -i 's/^ \(.*\):: \(.*\)$/  <dt>\1<\/dt>\n  <dd>\2<\/dd>/' file

出力が次のようになります。

# TODO #

 * Set up mail transfer agent
 * Reconfigure timezone

```bash
dpkg-reconfigure tzdata
```

# Hardware #
<dl>
  <dt>RAM</dt>
  <dd>2GB</dd>
</dl>

# Partitions #

<dl>
<dt>`/dev/sda1`</dt>
<dd>/boot</dd>
<dt>`/dev/sda2`</dt>
<dd>/</dd>
</dl>

できるだけ有効なHTMLが欲しい。すべてのオープンタグには終了タグが必要です。

ベストアンサー1

これはあなたが期待する以上のものかもしれませんが、あなたsedが望むものを達成するための最良の方法だと思いますsed

このスクリプトは次のとおりです。

  • 行の前に他の、またはがない場合は、<dl>含まれる各行の前に行が挿入されます。<dt><dt><dd><dl>

  • </dl>埋め込み行の後の行が含まれていない場合は、<dd>含まれている各行の後に1行が追加されます。<dd><dd>

スクリプトは、タグを挿入する前にタグを確認できるように、スペースを使用して前の行sedを覚えています。また、閉じるタグを追加できるように相対アドレス指定を使用します。 aがファイルの最後の行にあり、追加する必要があるかどうかを検出するには特別な場合が必要です。 test(および)とBranch()はロジックを実装するために広く使用されています。sed hold<d[tdl]><dl>ADDR,+N</dl><dd></dl>tTb

#!/bin/sh

sed '
    /<dt>/ {
        x                  # exchange pattern and hold space
        s/<d[tdl]>//       # subsitutue, just testing for pattern
        g                  # copy hold space back, overwriting pattern space
        t end              # branch to :end if previous subsitution successful
        i \
<dl>
    }

    $ {
        /<dd>/ ! b end     # if <dd> on last line, append </dl>
        a \
</dl>
    }

    /<dd>/,+1 {            # on each line containing <dd> and the line after
        /<dd>/ b end       # if does not contain <dd>, insert </dl>
        i \
</dl>
    }

:end
    h                      # copy pattern space to hold space for next round

' "$@"

スクリプトはサンプルデータを次のように変更します。

[...]

# Hardware #
<dl>
  <dt>RAM</dt>
  <dd>2GB</dd>
</dl>

# Partitions #

<dl>
<dt>`/dev/sda1`</dt>
<dd>/boot</dd>
<dt>`/dev/sda2`</dt>
<dd>/</dd>
</dl>

おすすめ記事