sed、awk、grepなどを使用してパターンに基づいてソースコードのメソッドの周りに「ラッパー」を追加する方法

sed、awk、grepなどを使用してパターンに基づいてソースコードのメソッドの周りに「ラッパー」を追加する方法

パターンに基づいてファイルにラッパーを追加するには?

たとえば、次のようなものがあります。

  ...
  find(css_policy_form_stage3).click
  with_ajax_wait
    expect(css_coverage_type_everquote).to be_visible
  end
  with_ajax_wait
    expect(css_coverage_type_everquote).to be_visible
  end
end
it "Stage 3" do
  select(coverage_type, from: css_coverage_type_everquote)
  find(css_has_auto_insurance).click
  ...

"with_ajax_wait"私は彼らの周りのブロックを「包装」したいと思いますit "waits" do ... end

言い換えれば、私は以下を得たいと思います:

  ...
  find(css_policy_form_stage3).click
  it "waits" do
    with_ajax_wait
      expect(css_coverage_type_everquote).to be_visible
    end
  end
  it "waits" do
    with_ajax_wait
      expect(css_coverage_type_everquote).to be_visible
    end
  do
end
it "Stage 3" do
  select(coverage_type, from: css_coverage_type_everquote)
  find(css_has_auto_insurance).click
  ...

注意事項と仮定:

  • インデントされたコードブロックの長さは常に3行です(with...expect...and end)。私が持っているよりも多くの内部コード行を許可したいのですが、最も簡単な場合は必要ありません。
  • ブロック自体にはさらに2つのインデントが必要です。
  • 関連していない他の端があります(「ステップ3」の前に示されている例)。
  • expectたとえば、インデントが始まるコード行だけをブロックするように内部パターンを指定できるとします。 awkは連続した行を読むことができるので、ツールになることができると思いますが、どのように書く必要があるのか​​がわかりません。

ファイルにラッパーを追加することは珍しいことではないので、これは一般的に便利なQ&Aだと思います。

前の質問とやや似ています。 awkを使用して単純な規則に従ってソースファイルをインデントする方法は?
しかし、この場合はラッパーとインデントを追加しました。

ベストアンサー1

1つの方法は次のとおりですsed

sed -E '/with_ajax_wait/,/end/{       # if line is in this range
H                                     # append to hold space
/end/!d                               # if it doesn't match end, delete it
//{                                   # if it matches
s/.*//                                # empty the pattern space
x                                     # exchange pattern space w. hold space
s/^(\n)( *)/\2it "waits" do\1\2/      # add first line + initial spacing
s/\n/&  /g                            # re-indent all other lines
G                                     # append hold space to pattern space
s/^(( *).*)/\1\2do/                   # add the closing 'do' + initial spacing
}
}
' infile

したがって、入力は次のようになります。

with_ajax_wait
  expect(css_coverage_type_everquote).to be_visible
end
  find(css_policy_form_stage3).click
  with_ajax_wait
    expect(css_coverage_type_everquote).to be_visible
  end
  something here
    with_ajax_wait
      expect(css_coverage_type_everquote).to be_visible
        got some more stuff here to do
          process it
        done
    end
  end

出力は次のとおりです

it "waits" do
  with_ajax_wait
    expect(css_coverage_type_everquote).to be_visible
  end
do
  find(css_policy_form_stage3).click
  it "waits" do
    with_ajax_wait
      expect(css_coverage_type_everquote).to be_visible
    end
  do
  something here
    it "waits" do
      with_ajax_wait
        expect(css_coverage_type_everquote).to be_visible
          got some more stuff here to do
            process it
          done
      end
    do
  end

ブロックはwith_ajax_wait常にend。必要に応じて、例は混乱しているので、最後を置き換えます
...(最初のブロックと2番目のブロックに使用します)たとえば、今回は(空白)の代わりにandを使用します。doendenddoBRE[[:blank:]]

sed '/with_ajax_wait/,/end/{
/with_ajax_wait/{
G
s/\([[:blank:]]*\)\(with_ajax_wait\)\(\n\)/\1it "waits" do\3  \1\2/
p
d
}
//!{
/end/!{
s/^/  /
}
/end/{
G
s/\([[:blank:]]*\)\(end\)\(\n\)/  \1\2\3\1end/
}
}
}
' infile

これにより、範囲内の各行が個別に処理され、範囲の最初の行と最後の行が再インデントされ、ラッパーが追加され、残りの行が再インデントされます。

おすすめ記事