Como usar o awk para indentar um arquivo de origem baseado em regras simples?

5

Como posso recuar o código-fonte com base em algumas regras simples?

Como exemplo, usei o sed e peço para transformar uma tabela de origem de HTML de selênio para o seguinte código do rspec. Como eu poderia recuar linhas entre describe e end ? Idealmente, gostaria de poder adicionar recuo a

describe "Landing" do
visit("http://some_url/url_reset")
visit("http://some_url/url_3_step_minimal_foundation")
# comments
expect(css_vehicle1_auto_year) to be_visible
end
describe "Stage1" do
wait_for_element_present(css_vehicle1_auto_year option_auto_year)
select(auto_year, from: css_vehicle1_auto_year)
...
end
describe "Stage2" do
fill_in(css_driver1_first_name, with: driver1_first_name)
fill_in(css_driver1_last_name, with: driver1_last_name)
...
submit(css_policy_form)
expect(css_vehicle1_coverage_type) to be_visible
end
describe "Stage3" do
wait_for_element_present(css_vehicle1_coverage_type)
select(coverage_type, from: css_vehicle1_coverage_type)
find(css_has_auto_insurance).click
...
submit(css_policy_form)
expect(css_quotes) to be_visible
end

então eu tenho

describe "Landing" do
  visit("http://some_url/url_reset")
  visit("http://some_url/url_3_step_minimal_foundation")
  # comments
  expect(css_vehicle1_auto_year) to be_visible
end
describe "Stage1" do
  wait_for_element_present(css_vehicle1_auto_year option_auto_year)
  select(auto_year, from: css_vehicle1_auto_year)
  ...
end
describe "Stage2" do
  fill_in(css_driver1_first_name, with: driver1_first_name)
  fill_in(css_driver1_last_name, with: driver1_last_name)
  ...
  submit(css_policy_form)
  expect(css_vehicle1_coverage_type) to be_visible
end
describe "Stage3" do
  wait_for_element_present(css_vehicle1_coverage_type)
  select(coverage_type, from: css_vehicle1_coverage_type)
  find(css_has_auto_insurance).click
  ...
  submit(css_policy_form)
  expect(css_quotes) to be_visible
end

O código-fonte para o sed e awk's existente está no link , mas é muito confuso e não é sobre o que estou perguntando. Eu tenho o jeito do sed simples e do awk, mas não tenho certeza de onde começar com este.

Seria ótimo se também pudesse lidar com a recursão. Não é essencial para mim, mas a generalização é provavelmente útil para outras pessoas que usam essa pergunta, ou seja,

describe "a" do
describe "b" do
stuff
more stuff
end
end

para

describe "a" do
  describe "b" do
    stuff
    more stuff
  end
end

btw Eu também estou fazendo essa conversão customizada em parte porque eu usei variáveis como objetos de página em selênio e eles bork a exportação interna para rspec.

    
por Michael Durrant 29.08.2015 / 03:35

1 resposta

8

com awk :

awk '
  /^end/ { sub("  ", "", indent) } # Or { indent = substr(indent, 3) }
  { print indent, $0 }
  /^describe/ { indent = indent"  " }
' <file
    
por 29.08.2015 / 04:10