Angenommen, ich habe diese (Puppet-)Datei mit einer Einrückung von 4 Leerzeichen (ich habe eine ganze Menge davon, die ich verarbeiten muss):
# 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,
}
}
Ich möchte sed verwenden, um jedes Vorkommen von 4 Leerzeichen am Anfang einer Zeile durch 2 Leerzeichen zu ersetzen, um dieses Ergebnis zu erhalten:
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,
}
}
Alles, was mir bisher eingefallen ist, ist Folgendes:
sed -i -e 's/^\s\{4\}/ /g' init.pp
Dies ersetzt jedoch nicht nur Vorkommen von 1x4-Leerzeichen und schließt daher keine tieferen Einrückungen ein.
Gibt es einen regulären Ausdruck, der jedes 4xLeerzeichen am Zeilenanfang durch 2xLeerzeichen ersetzen kann? Ist das überhaupt mit einfachen regulären Ausdrücken und sed möglich, oder muss ich auf awk/Perl/Python/Ruby umsteigen, da ich die Vorkommen zählen muss, um sie durch die gleiche Anzahl zu ersetzen?
BEARBEITEN
Diese Frage ist dumm (obwohl in einem einfachen Fall alles funktioniert). Aber ich sollte meinen Code nicht ohne ein Tool formatieren, das die Sprache meines Codes versteht (und das ist Puppet). Selbst wenn ich den perfekten regulären Ausdruck habe (wie in den Antworten angegeben), habe ich das Problem, dass die Einrückung erneut beschädigt wird, wenn ich den regulären Ausdruck versehentlich mehr als einmal anwende. Die Puppet-Leute arbeiten an diesem Problem:http://projects.puppetlabs.com/issues/8031bis das Problem gelöst ist, muss ich beim Konvertieren von Dateien vorsichtig sein. Oder selbst einen richtigen Formatierer schreiben (was nicht so schwer sein sollte).
Antwort1
perl -pe 's{^((?: )+)}{substr($&, length($&)/2)}e'
Antwort2
Möglicherweise versuchen Sie, das falsche Tool zu verwenden. Möglicherweise kommen Sie zu einer Sed-Lösung, aber es gibt ein Tool, das dafür entwickelt wurde und viel schneller funktioniert.
http://perltidy.sourceforge.net/
Schauen Sie sich perltidy an. Dies ist ein Perl-Modul, das in den meisten Distributionen verfügbar ist.
Wenn es richtig installiert ist, kann es durch Eingabe von „perltidy“ aufgerufen werden. Um das gewünschte Ergebnis zu erzielen, sollte Folgendes funktionieren.
perltidy -i=2 <filename>
Dadurch sollte eine neue Datei mit den Änderungen und der Erweiterung .tdy erstellt werden. Obwohl perltidy ursprünglich für Perl geschrieben wurde, funktioniert es auch mit vielen anderen Programmiersprachen. Es kann problemlos in gängigen Editoren aufgerufen und in Verbindung mit einer allgemeinen .tidyrc-Datei verwendet werden, um einen Programmierstandard beizubehalten/durchzusetzen. Es stehen umfangreiche Optionen zur Verfügung, mit denen Sie jeden Aspekt der Behandlung des Codes steuern können.
Antwort3
Da die Perltidy-Antwort bei Ihrem Code nicht funktioniert hat, verwenden Sie dies.
perl -pe 's{^(\s*)}{" " x (length($1)/2)}e'
Übergeben Sie den Namen der Datei am Ende der Zeile oder leiten Sie die Datei an STDIN weiter. STDOUT ist Ihr geänderter Code.