sed: замінити кожне випадок на 4 пробіли (на початку рядка) на 2 пробіли


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, оскільки я повинен рахувати випадки, щоб замінити їх тим же номером?

EDIT

Це питання дурне (хоча для простого випадку все працює). Але я не повинен форматувати свій код без інструменту, який розуміє мову мого коду (який є ляльковий). Навіть якщо я маю ідеальний регулярний вираз (наприклад, як це передбачено у відповідях), у мене є проблема, що якщо я випадково застосую регулярний вираз більше 1 разу, відступ знову порушується. Хлопці ляльок працюють над цим питанням: http://projects.puppetlabs.com/issues/8031 поки не буде вирішено, я повинен бути обережним при конвертації файлів. Або напишіть собі справжній форматер (який не повинен бути таким жорстким).


З "/ g" в кінці, він повинен "глобально" замінити шаблон в межах рядка. Тому я вважаю, що вона повинна охоплювати кратні значення 4 відступу простору.
pottsdl

@pottsdl Не з ^ (початок рядка) ...
Bob

Відповіді:



2

Можливо, ви намагаєтеся використати неправильний інструмент. Цілком можливо, що ви могли б прийти до рішення sed, але є інструмент, побудований для цього, який буде працювати набагато швидше.

http://perltidy.sourceforge.net/

Подивіться на perltidy. Це модуль perl, який доступний у більшості дистрибутивів.

Якщо встановлено правильно, його можна викликати, натиснувши 'perltidy'. Для досягнення того, що ви шукаєте, має працювати наступне.

perltidy -i=2 <filename> 

Це має створити новий файл із змінами з розширенням .tdy. Хоча perltidy був написаний спочатку для perl, він може і працює добре на багатьох інших мовах коду. Його можна легко викликати в популярних редакторах і використовувати в поєднанні з загальним .tidyrc можна використовувати для підтримки / застосування стандарту кодування. Є великі варіанти, які дозволять вам контролювати кожен аспект його обробки коду.


perltidy, схоже, підходить лише до скриптів Perl: "Perltidy - це скрипт Perl, який відступає і переформатує скрипти Perl, щоб зробити їх легше читати". При виклику на моєму прикладі він скаржиться на синтаксичні помилки.
ifischer

Я використовував його ефективно на C і Java, хоча, що сказав, що всі вони кілька C засновані і подібні синтаксис. Можливо, виправлення деяких варіантів може усунути помилку, але це може бути неможливо.
AaronM

2

Оскільки відповідь perltidy не працювала на вашому коді, використовуйте це.

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

Передайте ім'я файлу в кінці рядка або вкажіть файл у STDIN. STDOUT буде вашим зміненим кодом.


heh бачать хтось ще забезпечений той же той час, коли я тестував це.
AaronM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.