デフォルトでは、2つの文字列間の内容を取得しようとしていますが、次のように同じ文字をN回繰り返します。
===
This is a test
===
====
Another test
====
==
Last test
==
もちろん、上記は単なる例です。私の試みと結果は次のとおりです。
sed -u '/==/!d;s//&\n/;s/.*\n//;:a;/==/bb;$!{n;ba};:b;s//\n&/;P;D' testfile
与える
=
This is a test
=
Another test
Last test
上記のいずれかを使用する場合testfile
:
Last test
これにより、必要な結果が得られます(ただし、改行があまりにも多くなりますが、この例では問題ありません)。
上記の方法は、これらの繰り返し文字のインスタンスが1つしかない場合、または内容を含む一意の文字列ペアである場合にのみ機能します。
繰り返される文字数が同じ2つの文字列間の内容を取得するには?私はこれを使用するか、grep
それを達成することをsed
好みます。awk
答え1
私たちは使用アッ次のトリガロジックを使用して開いた状態から閉じた状態に切り替えるユーティリティです。
$ awk -v str="==" '
$0""==str{f=!f;next};f
' testfile
Last test
Posixlyを使うsedトリガロジックの構成を実装できます。
sed -ne '
/^==$/{
x; # access state info from hold
s/^$/0/; # initialize state
y/01/10/; # toggle state
x; # save state in hold
d; # next
}
G;/\n1/P
' testfile
ストリームエディタのGNUバージョンを使用するsed拡張モードで-E
$ sed -Ee '
$!N; /^(\S)\1+\n/!D
:loop
$d;N
s/^(.*)\n(.*)\n\1$/\2/;t
bloop
' testfile
This is a test
Another test
Last test
メモ:-
- コマンドを介して
N
2行のパターンスペースを維持します。 - ゴールデンラインに達するまでラインを拒否し続けます(=>パターンスペースの最初の部分には空白以外の文字の単一タイプのみが含まれています)。
- そのような線を見つけたら、道路上の線と正確に一致する複製が複数表示されるまで繰り返します。私たちは最初のグループを見つけました。
- eofに達するまでこのプロセスを繰り返します。
...
トリガー演算子の使用真珠次のようにこれを行うことができます。
perl -lne 'print if
/^(\S)\1+$(?{$a=$_})/ ... $_ eq $a and $_ ne $a;
' testfile
固定された所定の文字列を検索する方がはるかに簡単です。それ以降は正規表現を書く必要はなく、文字列同等性テストで十分です。
$ perl -nlse 'print if
$_ eq $a ... $_ eq $a and $_ ne $a;
' -- -a=== testfile
$ sed -Ee '
/^==$/!d
$!N
:a
$d;N
s/^(.*)\n(.*)\n\1$/\2/;t
ba
' testfile
答え2
長すぎます。
$ sed '/^==*$/,//{//!p};d' testfile
This is a test
Another test
Last test
一見すると、単純な範囲はすべてのペアを印刷します(ループは必要ありません)。
$ sed -n '/^=/,//p' testfile
===
This is a test
===
====
Another test
====
==
Last test
==
=
()で始まる行と次の繰り返し正規表現()の間の//
すべての行を印刷します。
ラインで改善できます。ただ含まれています=
:/^==*$/
。
すべてのマーカーを削除します。
$ sed -n '/^==*$/,//H;${x;s/\n==*//g;s/^\n//;p}' testfile
This is a test
Another test
Last test
またはより短い形式で:
$ sed -n '/^==*$/,//{//d;p}' testfile
This is a test
Another test
Last test
正確な数量を一致させるには、=
正規表現を次のように変更します。
$ sed -n '/^==$/,//{//d;p}' testfile
Last test
そして、その-n
オプションを避けるには:
$ sed '/^==$/,//{//!p};d' testfile
Last test
awkでは、次のようにできます。
$ awk 'p==0 && /^==*$/ {p=1;next}
p==1 && /^==*$/ {p=0}
p
' testfile
This is a test
Another test
Last test
またはあまり明示的ではありません:
awk ' /^==*$/ { p = !p ; next}
p
' testfile
答え3
私は以下を使用しますperl
:
$ perl -0777 -ne 'print $3 while /^((\S)\2+\n)(.*?)^\1/smg' < your-file
This is a test
Another test
Last test
またはpcregrep
:
$ pcregrep -Mo3 '(?s)^((\S)\2+\n)(.*?)\n?^\1' < your-file
This is a test
Another test
Last test
固定区切り記号間のコンテンツを返す場合:
$ pcregrep -Mo1 '(?s)^==\n(.*?)\n?^==$' < your-file
Last test
答え4
注文する:
awk '{a[++i]=$0}/==/{for(x=NR-1;x<NR;x++)print a[x]}' filename|sed '/^$/d'
出力
This is a test
Another test
Last test