2

Скажем, у меня есть этот (кукольный) файл с отступом в 4 пробела (у меня есть куча из них, которые я должен обработать):

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

Я хочу использовать sed для замены каждого вхождения 4 пробелов в начале строки на 2 пробела, чтобы получить такой результат:

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

Все, что я дошел до этого, это:

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

но это не только заменит вхождения 1x4 пробелов и, следовательно, не будет включать более глубокие отступы.

Существует ли регулярное выражение, которое может заменить каждое 4xspace в начале строки на 2xspace? Возможно ли это даже с простыми регулярными выражениями и sed, или мне нужно переключиться на awk/perl/python/ruby, так как я должен считать случаи, чтобы заменить их на одно и то же число?

РЕДАКТИРОВАТЬ

Этот вопрос глуп (хотя для простого случая все работает). Но я не должен форматировать свой код без инструмента, который понимает язык моего кода (то есть Puppet). Даже если у меня есть идеальное регулярное выражение (как указано в ответах), у меня есть проблема в том, что, если я случайно применю регулярное выражение более 1 раза, отступ снова будет нарушен. Ребята из Puppet работают над этой проблемой: http://projects.puppetlabs.com/issues/8031, пока она не будет решена, я должен быть осторожен при конвертации файлов. Или сам напиши настоящий форматтер (что не должно быть так сложно).

3 ответа3

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

Возможно, вы пытаетесь использовать не тот инструмент. Вполне возможно, что вы могли бы прийти к решению sed, но для этого существует инструмент, который будет работать намного быстрее.

http://perltidy.sourceforge.net/

Посмотрите на Perltidy. Это Perl-модуль, который доступен в большинстве дистрибутивов.

Если он установлен правильно, его можно вызвать, набрав «perltidy». Для достижения того, что вы ищете, должно работать следующее.

perltidy -i=2 <filename> 

Это должно создать новый файл с изменениями с расширением .tdy. Хотя perltidy изначально был написан для perl, он может работать и хорошо работает на многих других языках кода. Его можно легко вызывать в популярных редакторах и использовать вместе с обычным .tidyrc, который можно использовать для поддержки / обеспечения соблюдения стандарта кодирования. Доступны широкие возможности, которые позволят вам контролировать каждый аспект обработки кода.

2

Поскольку ответ perltidy не сработал в вашем коде, используйте это.

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

Передайте имя файла в конце строки или передайте файл в STDIN. STDOUT будет вашим измененным кодом.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .