Digamos que eu tenha este arquivo (fantoche) com um recuo de 4 espaços (tenho vários 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,
}
}
Quero usar sed para substituir cada ocorrência de 4 espaços no início de uma linha por 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 o que descobri até agora foi isto:
sed -i -e 's/^\s\{4\}/ /g' init.pp
mas isso não substituirá apenas as ocorrências de espaços 1x4 e, portanto, não incluirá recuos mais profundos.
Existe um regex que pode substituir cada 4xspace no início de uma linha por 2xspace? Isso é possível com regexes simples e sed, ou preciso mudar para awk/perl/python/ruby, já que preciso contar as ocorrências para substituí-las pelo mesmo número?
EDITAR
Esta pergunta é estúpida (embora para um caso simples tudo funcione). Mas eu não deveria formatar meu código sem uma ferramenta que entenda a linguagem do meu código (que é o Puppet). Mesmo que eu tenha o regex perfeito (como fornecido nas respostas), tenho o problema de que, se eu aplicar acidentalmente o regex mais de uma vez, o recuo será quebrado novamente. Os caras do Puppet estão trabalhando nesse problema:http://projects.puppetlabs.com/issues/8031até que seja resolvido, tenho que ter cuidado na hora de converter os arquivos. Ou escreva eu mesmo um formatador real (o que não deve ser tão difícil).
Responder1
perl -pe 's{^((?: )+)}{substr($&, length($&)/2)}e'
Responder2
Você pode estar tentando usar a ferramenta errada. É possível que você chegue a uma solução sed, mas existe uma ferramenta criada para isso que funcionará muito mais rapidamente.
http://perltidy.sourceforge.net/
Dê uma olhada em Perltidy. É um módulo Perl que está disponível na maioria das distribuições.
Se estiver instalado corretamente, pode ser invocado digitando 'perltidy'. Para conseguir o que você procura, o seguinte deve funcionar.
perltidy -i=2 <filename>
Isso deve criar um novo arquivo com as alterações com extensão .tdy. Embora perltidy tenha sido 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 para manter/impor um padrão de codificação. Existem amplas opções disponíveis que permitirão controlar todos os aspectos do tratamento do código.
Responder3
Como a resposta perltidy não funcionou no seu código, use isto.
perl -pe 's{^(\s*)}{" " x (length($1)/2)}e'
Passe o nome do arquivo no final da linha ou canalize o arquivo para STDIN. STDOUT será seu código modificado.