Digamos que tengo este archivo (títere) con una sangría de 4 espacios (tengo varios que tengo que procesar):
# 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,
}
}
Quiero usar sed para reemplazar cada aparición de 4 espacios al comienzo de una línea con 2 espacios, para obtener 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,
}
}
Todo lo que se me ocurrió hasta ahora es esto:
sed -i -e 's/^\s\{4\}/ /g' init.pp
pero esto no sólo reemplazará las apariciones de espacios de 1x4 y, por lo tanto, no incluirá sangrías más profundas.
¿Existe una expresión regular que pueda reemplazar cada 4xspace al comienzo de una línea con 2xspace? ¿Es eso posible con expresiones regulares simples y sed, o tengo que cambiar a awk/perl/python/ruby, ya que tengo que contar las apariciones para reemplazarlas con el mismo número?
EDITAR
Esta pregunta es estúpida (aunque para un caso simple, todo funciona). Pero no debería formatear mi código sin una herramienta que entienda el lenguaje de mi código (que es Puppet). Incluso si tengo la expresión regular perfecta (como se proporciona en las respuestas), tengo el problema de que si accidentalmente aplico la expresión regular más de una vez, la sangría se rompe nuevamente. Los chicos de Puppet están trabajando en ese tema:http://projects.puppetlabs.com/issues/8031Hasta que se solucione, tengo que tener cuidado al convertir archivos. O escribir yo mismo un formateador real (lo cual no debería ser tan difícil).
Respuesta1
perl -pe 's{^((?: )+)}{substr($&, length($&)/2)}e'
Respuesta2
Es posible que esté intentando utilizar la herramienta incorrecta. Es posible que pueda llegar a una solución sed, pero existe una herramienta diseñada para esto que funcionará mucho más rápido.
http://perltidy.sourceforge.net/
Echa un vistazo a la perltidy. Es un módulo perl que está disponible en la mayoría de las distribuciones.
Si está instalado correctamente, se puede invocar escribiendo 'perltidy'. Para lograr lo que busca, lo siguiente debería funcionar.
perltidy -i=2 <filename>
Esto debería crear un nuevo archivo con los cambios con una extensión .tdy. Si bien perltidy se escribió inicialmente para perl, puede funcionar bien, y funciona, en muchos otros lenguajes de código. Puede invocarse fácilmente en editores populares y usarse junto con un .tidyrc común para mantener/hacer cumplir un estándar de codificación. Hay amplias opciones disponibles que le permitirán controlar cada aspecto del tratamiento del código.
Respuesta3
Como la respuesta perltidy no funcionó en su código, use esto.
perl -pe 's{^(\s*)}{" " x (length($1)/2)}e'
Pase el nombre del archivo al final de la línea o canalice el archivo a STDIN. STDOUT será su código modificado.