Text-Processing
如何使用 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 行長(帶有…期望…和結束)。允許超過 i 內部程式碼行會很好,但對於最簡單的情況不需要。
- 塊本身應該有一個額外的 2 個空格縮進。
- 還有其他不相關的端(範例顯示在“第 3 階段”之前
- 能夠指定內部模式也很好,例如只有這些
expect
程式碼行開始縮進的塊。我認為 awk 可能是由於能夠讀取連續行的工具,但我很難知道如何編寫它。我想這是一個普遍有用的問答,因為在文件中添加包裝器並不少見。
有點類似於我之前的問題: How to use awk to indent a source file based on simple rules?
但是在這種情況下,我添加了包裝器和縮進。
這是一種方法
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
.如果需要,將結尾替換
do
為end
您的範例令人困惑…(您用於end
第一個塊和do
第二個塊)例如這次使用BRE
and[[:blank:]]
而不是(space):
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 ``` This one is processing each line in that range separately, the first and the last ones in the range are re-indented and wrappers are added, the rest of the lines are just re-indented.`