2

Say I have this (puppet) file with an indentation of 4 spaces (I have a bunch of them that I have to process):

# 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,
    }
}

I want to use sed to replace each occurence of 4 spaces at the beginning of a line with 2 spaces, to get this result:

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,
  }
}

All I came up so far ist this:

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

but this will not only replace occurences of 1x4 Spaces and therefore not include deeper indentations.

Is there a regex which can replace each 4xspace at beginning of a line with 2xspace? Is that even possible with simple regexes and sed, or do I have to switch to awk/perl/python/ruby, since I have to count the occurences to replace them with the same number?

EDIT

This question is stupid (although for a simple case, it all works). But I should not format my code without a tool that does understand the language of my code (which is Puppet). Even if I have the perfect regex (like provided inside the answers), I have the problem that if I accidentally apply the regex more than 1 time, the indentation is broken again. The Puppet guys are working on that issue: http://projects.puppetlabs.com/issues/8031 until it is solved, I have to be careful when converting files. Or write a real formatter myself (which should not be that hard).

2
  • With the "/g" at the end, it should "globally" replace the pattern within the line. So I would think that it should cover multiples of the 4 space indentation.
    – pottsdl
    May 8, 2012 at 14:39
  • @pottsdl Not with the ^ (start of line)...
    – Bob
    May 8, 2012 at 14:40

3 Answers 3

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

You might be trying to use the wrong tool. It is possible that you could arrive at a sed solution but there is a tool built for this that will work much more quickly.

http://perltidy.sourceforge.net/

Take a look at perltidy. It is a perl module that is available in most distributions.

If it is installed correctly it can be invoked by typing 'perltidy'. To achieve what you are looking for the following should work.

perltidy -i=2 <filename> 

This should create a new file with the changes with a .tdy extension. While perltidy was written initially for perl, it can and does work well on many other languages of code. It can be easily invoked within popular editors and used in conjunction with a common .tidyrc can be used to maintain/enforce a coding standard. There are extensive options available that will let you control every aspect of its treatment of the code.

2
  • perltidy seems to be suited only towards Perl scripts: "Perltidy is a Perl script which indents and reformats Perl scripts to make them easier to read". When invoked on my example, it complains about Syntax errors. May 8, 2012 at 15:02
  • I have used it effectively on C and Java, though that said those are all somewhat C based and share similar syntax. It is possible that tweaking some of the options might resolve the error, but it may not be possible.
    – AaronM
    May 8, 2012 at 15:19
2

As the perltidy answer did not work on your code use this.

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

Pass the name of the file at the end of the line or pipe the file into STDIN. STDOUT will be your modified code.

1
  • heh see someone else provided the same while I was testing it.
    – AaronM
    May 8, 2012 at 15:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .