4

次のような構造のファイルがあります。

BOF

-------Title1-------
stuff here
some stuff

-------Title2-------
extra things
extra things
extra things

-------Title3-------
and some stuff
   here

...

-------Title4-------
stuff

EOF

今、私はこのようなことをしたいと思います:

grep-by-section KEYWORD DELIMITER my-file

となることによって

grep-by-section "some" "^---" my-file

出力

-------Title1-------
stuff here
some stuff

-------Title3-------
and some stuff
   here

特定のキーワードを見つけたいのですが、発見ごとに、既知の区切り文字の間のブロック全体を出力したいと考えています。どうやってやるの?sedここで失敗します。

ここでの区切り文字は「------」ですが、たとえば [0-9]{8} 形式の数字のような別のものでもかまいません。

私が解決できなかった同様の問題は、ブロックの内容を出力する代わりに、ブロックのタイトルだけを出力することです。

perlよりも解決しやすいようですsed

4

3 に答える 3

4
#!/usr/bin/perl
my ($search, $del) = splice(@ARGV, 0, 2);
local $/;
while (<>) {
   for (/($del(?:(?!$del).)*)/smg) {
      print if /$search/sm;
   }
}

ノート:

  • local $/次の readline が、一度に 1 行ずつではなく、一度に 1 ファイルずつ読み取るようにします。
  • (?:(?!STRING).)*STRINGそのまま[^CHAR]*ですCHAR
于 2013-03-30T02:56:04.733 に答える
0

これらのレコード間に真の空の行がある場合、これらの区切り記号を使用する必要はありません。これで十分です。

awk '/KEYWORD/' RS= ORS='\n\n' file

それ以外の場合は、次の awk を試すこともできます。

awk '
  $0~key{
    f=1
  }
  $0~del{
    if(f)print s
    f=0
    s=$0
    next
  }
  {
    s=s RS $0
  }
  END{
    if(f)print s
  }
' key="KEYWORD" del="DELIMITER" file

一行で:

awk '$0~key{f=1} $0~del{ if(f)print s ; f=0; s=$0; next } {s=s RS $0} END{ if(f)print s }' key="KEYWORD" del="DELIMITER" file
于 2013-03-30T10:48:29.070 に答える