最初の一致する括弧の間の内容を印刷します。

最初の一致する括弧の間の内容を印刷します。

入力例:

START{
    some text

    {
      more text}
almost there
}
nothing important{
...

希望の出力:

START{
    some text

    {
      more text}
almost there
}

最初の開いたブラケットは別の位置にある可能性があります。

START{...
START {...
START
{...

先頭には特殊文字を含めることもできます。例: *

{}STARTから始まるすべての内容と最初の一致の間のすべての内容(bash)を印刷したいと思います。私はそれが見つかると増加し{、見つかると減少するカウンターを持つと思います}。結果が0の場合は印刷を停止します(中括弧は常に一致します)。

答え1

すべてのUnixシステムのすべてのシェルで任意のawkで動作する簡単な無差別方法:

$ cat tst.awk
s=index($0,"START") { $0=substr($0,s); f=1 }
f { rec = rec $0 RS }
END {
    len = length(rec)
    for (i=1; i<=len; i++) {
        char = substr(rec,i,1)
        if ( char == "{" ) {
            ++cnt
        }
        else if ( char == "}" ) {
            if ( --cnt == 0 ) {
                print substr(rec,1,i)
                exit
            }
        }
    }
}

$ awk -f tst.awk file
START{
    some text

    {
      more text}
almost there
}

答え2

そしてpcregrep

start_word='START'
pcregrep -Mo "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" < your-file

zsh組み込み機能を使用します。

set -o rematchpcre
start_word='START'
[[ $(<your-file) =~ "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" ]] &&
  print -r -- $MATCH

(?1)上記で検討した最初のペアの正規表現である(...)PCREの再帰正規表現機能を使用します。

pcregrep両方がない場合は、zshいつでも次に切り替えることができます。本物(PCREperlからP):

perl -l -0777 -sne '
    print $& if /\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})/s
  ' -- -start_word='START' < your-file

perlこれらのいずれかを除いてすべてが$start_word含まれていないとします\E。)

関連情報