Text-Processing

如何使用 sed、awk、grep 和朋友根據模式在原始碼中的方法周圍添加“包裝器”

  • September 5, 2015

如何根據模式將包裝器添加到文件中?

例如,我有以下內容:

 ...
 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.

如果需要,將結尾替換doend您的範例令人困惑…(您用於end第一個塊和do第二個塊)例如這次使用BREand[[: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.`

引用自:https://unix.stackexchange.com/questions/227476