2016-04-18 5 views
2

上で私は、単一のライン上のどこかに開始する複数の異なる:variablerolename:部分がある場合もありますマッチパターンはおそらく改行のみ印刷パターン

:variablerolename:`text may span newline` 

ためスフィンクス.rstのテキストファイルを検索しています。

ので、入力例として、私が持っている:

yada :role2:`texty text` yada :role:`text 
line` yada filler 
yada yada :role:`text of role` yada yada :role2:`start of text 
rest of text` 
more text :rolename:`Text after this role` 
filler :otherrole:`This role 
text` filler 

は、私は限り

grep -P '(?s):[a-z].*:`.*`' filename 

としてgottenをした。しかし、私は、これは適切に複数のマッチングされたとは思わないの答えを検索:役割:出力の1行が得られるので、行のブロックは

yada yada :role:`text of role` yada yada :role2:`start of text 

ですが、それ以外のロール2終了までのテキストは、次の行には表示されません。

私が望む出力は、ロール名とバッククォートされたテキストだけで、各インスタンスは1行にあり、プレテキストとポストテキストはありません。だから、のようなもの:私は|sort|uniqへでこの出力を渡すことになります

:role2:`texty text` 
:role:`text line` 
:role:`text of role` 
:role2:`start of text rest of text` 
:rolename:`Text after this role` 
:otherrole:`This role text` 

ので、単一の行が必要です。

私はRHEL 6.7で利用できるものを使用することに限定されてる(

  • GNUのbashのは、バージョン4.1.2
  • GNU Awkの3.1.7
  • はgrep(ので、最新の機能が使用できない可能性があります) GNUのgrepの)2.20
  • GNU sedのバージョンそれはあなたの質問から明らかではないのですが、これは何が必要かもしれ4.2.1
+0

:出力のみのユニークな値に

$ awk -v RS=':[^:]+:'[^']+'' 'RT{gsub(/\n/," ",RT); print RT}' file :role:'text of role' :role2:'start of text end of text' 

'awk'を使って' RS'を設定した場合、あなたはもっと簡単な時間を取るかもしれません':'。それでも、引用符で囲まれたテキストを取り出して* previous *レコードにマッピングする必要がありますが、それは実行可能でなければなりません。 –

+0

あなたがしようとしていることを言うのは難しいです。あなたの質問を編集して、簡潔でテスト可能なサンプル入力とその入力が与えられた場合の期待出力、すなわち[mcve]を投稿してください。今のところ、いくつかの不明瞭な例があるようです。 –

+0

あなたはそうです。ごめんなさい。それをきれいにしようとしました。 – Torfey

答えて

1

は(マルチchar型のRS用のGNU AWKを使用していますND RT):

awk -v RS=':[^:]+:`[^`]+`' 'RT{print RT}' file 

例:

$ cat file 
yada yada :role:`text of role` yada yada :role2:`start of text 
end of text` yada yada 

$ awk -v RS=':[^:]+:`[^`]+`' 'RT{print RT}' file 
:role:`text of role` 
:role2:`start of text 
end of text` 

空白文字を持つ任意の改行を置き換えるためには、単に次のようになります。

$ awk -v RS=':[^:]+:`[^`]+`' 'RT{gsub(/\n/," ",RT); if (!seen[RT]++) print RT}' file 
:role:`text of role` 
:role2:`start of text end of text` 
+0

これは私を非常に近づけます。あなたの例が示すように、バッククォートされたテキストの間に改行があります。もし私がその改行を取り除くことができれば、私はそれがまさに私が必要とするものになるでしょう。 – Torfey

+1

awk -v RS = ':[^:] +: '[^'] +' 'RT {print gensub(/ * [\ r \ n]]は、 + */""、 "g"、RT)} 'ファイル'。 (クラップ。RS定義のバックスラッシュを失ってしまいました。) – joepd

+0

1行でそれぞれを結合するために必要なことを追加すると思います。そして、 'sort | uniq'が出力時に意図したとおりに動作するように、改行がバッククォートの間にあった場所をきちんと入れます。 [バッククォートで終わっていない行と一致させるためにawkの出力に別のツールを使用しようとしていましたが、その行を次の行に結合しようとしていました。] – Torfey

関連する問題