sed 正規表現アドレス範囲からの行数の減算(または加算)

sed 正規表現アドレス範囲からの行数の減算(または加算)

次の内容を含む複数のICSファイルがあります。

...
PRIORITY:4
DESCRIPTION:this
  was
  a
  triumph
COMPLETED:20180101T160000
...

私はDESCRIPTION主な問題を解決することに興味があります。このキーはDESCRIPTIONICSファイルのどこにでも表示できます。これはいいえ常に鍵を守ってくださいCOMPLETED

を使用するにはed

/DESCRIPTION/;/^[^ ]/-1p

結果:

DESCRIPTION:this
  was
  a
  triumph

ところで、sedこのような能力はないようです。

sed -n '/DESCRIPTION/,/^[^ ]/-1p' filename

明らかにする

sed: -e 式 #1、文字 22: 不明なコマンド: `-'

私が望むことをする方法はありますかsed

この特定の問題を解決するには

この問題は次の方法で解決できます。

sed -n '/DESCRIPTION:/,/^\S/ { /\(DESCRIPTION\|^\s\)/p }' example.ics

でも、とても薄くて長い感じがします。

awkこれもサポートされていないようですが、/begpat/,/endpat/-1次のような結果が出ます。

BEGIN { endpat = "^(DESCRIPTION|\\s)" }
/^DESCRIPTION/, $0 !~ endpat {
    if ($0 ~ endpat) {print}
}

答え1

あなたはすでにかなり近づいています。

sed '/DESCRIPTION/p;//,/^[^ ]/!d;//d' filename

やりたいことをします。なぜ?

  • 範囲を定義し、その範囲外のすべての項目を削除できます。/start/,/stop/!d
  • 次に、一致する最後の行も削除しようとします。これは//dこれを行います(空のパターンが//最後のパターンと一致するため、この行に/stop/なります)。
  • しかし、あなたの場合、パターンは最初の行とも一致します。運命!まず印刷してみましょうp。それから私は私が示したコマンドを受け取ります(再び空のモードを使う)。

さまざまな方法で更新

あなたの意見ではこれを「解決方法」と呼びます。実際、自分自身のためにもう少し異なるsedアプローチを選択します。

sed '/^ /{H;d;};x;/^DESCRIPTION/!d' filename

これはカップルにとって自然なことですが、sed一部には最初は奇妙に見えるかもしれません。次は「覚えてほしい「-方法。それは何ですか?インデントのない行に会うたびに、「前の行を覚えてほしい、印刷する価値があったらいいな」と思います。スペースを解放することで、次のことができます。単純にxパターンスペースを変更し、スペースを予約し、d開始しない場合は削除しますDESCRIPTION(起動するとデフォルトで印刷されます)。

利点は、xインデントされていないすべての行が自動的に予約済みスペースにあるため、予約済みスペースにインデントされた行だけを追加することですH。これがこの/^ /{H;d;}部分の目的です(dこの行の出力や追加処理を避けるため)。

今日、プログラマーはその反対の仕事をしています。次のループを実行できます。

sed '/DESCRIPTION/!d
  :loop
  N;/\n[^ ].*/!bloop
s///' filename

つまり、DESCRIPTIONキーワードが表示されるまですべてを削除し、ループを開始して行を収集し、N空白以外の行があるまで繰り返します\n[^ ].*。この場合、最後の行を削除します(再び空のパターンを使用)。

これも機能しますが、機能しませんsed

答え2

はい、sedは次のアドレス範囲をサポートしています。

sed -n '/string1/,/string2/p file

あなたの場合は、-E正規表現を拡張するオプションを試してください。

sed -nE '/this/,/^[^ ]/p' filename

関連情報