sed: substitua cada ocorrência de 4 espaços (no início de uma linha) por 2 espaços

2

Digamos que eu tenha esse arquivo (fantoche) com um recuo de 4 espaços (tenho um monte deles que preciso processar):

# init.pp
class hardwareid (
    $package_name      = $hardwareid::params::package_name,
    $package_category  = $hardwareid::params::package_category,
    $package_ensure    = $hardwareid::params::package_ensure

) inherits hardwareid::params {

    package { "${package_name}":
        name      => $package_name,
        category  => $package_category,
        ensure    => $package_ensure,
    }
}

Eu quero usar sed para substituir cada ocorrência de 4 espaços no início de uma linha com 2 espaços, para obter este resultado:

class hardwareid (
  $package_name      = $hardwareid::params::package_name,
  $package_category  = $hardwareid::params::package_category,
  $package_ensure    = $hardwareid::params::package_ensure

) inherits hardwareid::params {

  package { "${package_name}":
    name      => $package_name,
    category  => $package_category,
    ensure    => $package_ensure,
  }
}

Tudo que eu criei até agora é isso:

sed -i -e 's/^\s\{4\}/  /g' init.pp

mas isso não apenas substituirá ocorrências de Espaços 1x4 e, portanto, não incluirá recuos mais profundos.

Existe um regex que pode substituir cada espaço 4x no início de uma linha com espaço 2x? Isso é possível com regexes simples e sed, ou eu tenho que mudar para awk / perl / python / ruby, já que eu tenho que contar as ocorrências para substituí-las pelo mesmo número?

EDITAR

Esta pergunta é estúpida (embora, para um caso simples, tudo funcione). Mas não devo formatar meu código sem uma ferramenta que compreenda a linguagem do meu código (que é Puppet). Mesmo se eu tiver o regex perfeito (como fornecido dentro das respostas), tenho o problema de que, se eu aplicar acidentalmente o regex mais de uma vez, o recuo é quebrado novamente. Os caras do Puppet estão trabalhando nessa questão: link até que seja resolvido, eu tenho que ter cuidado ao converter arquivos. Ou escreva um formatador real (que não deveria ser tão difícil).

    
por ifischer 08.05.2012 / 16:23

3 respostas

4
perl -pe 's{^((?:    )+)}{substr($&, length($&)/2)}e'
    
por 08.05.2012 / 17:11
2

Você pode estar tentando usar a ferramenta errada. É possível que você chegue a uma solução de segurança, mas existe uma ferramenta criada para isso que funcionará muito mais rapidamente.

link

Dê uma olhada no perltidy. É um módulo perl disponível na maioria das distribuições.

Se estiver instalado corretamente, pode ser chamado digitando 'perltidy'. Para alcançar o que você está procurando, o seguinte deve funcionar.

perltidy -i=2 <filename> 

Isso deve criar um novo arquivo com as alterações com uma extensão .tdy. Enquanto perltidy foi escrito inicialmente para perl, ele pode funcionar bem em muitas outras linguagens de código. Ele pode ser facilmente invocado em editores populares e usado em conjunto com um .tidyrc comum que pode ser usado para manter / impor um padrão de codificação. Existem várias opções disponíveis que permitem controlar todos os aspectos do tratamento do código.

    
por 08.05.2012 / 16:51
2

Como a resposta perdedora não funcionou no seu código, use isso.

perl -pe 's{^(\s*)}{" " x (length($1)/2)}e'

Passe o nome do arquivo no final da linha ou envie o arquivo para STDIN. STDOUT será seu código modificado.

    
por 08.05.2012 / 17:20

Tags