2017-08-24 2 views
2

ich eine Datei mit folgendem Aufbau haben:Sed/awk: Ausrichten Wörter in einer Datei

# ################################################################# 
# TEXT: MORE TEXT 
# TEXT: MORE TEXT 
# ################################################################# 

___________________________________________________________________ 
ITEM 1 
___________________________________________________________________ 
PROPERTY1:  VALUE1_1 
PROPERTY222: VALUE2_1 
PROPERTY33: VALUE3_1 
PROPERTY4444: VALUE4_1 
PROPERTY55: VALUE5_1 

Description1: Some text goes here 
Description2: Some text goes here 

___________________________________________________________________ 
ITEM 2 
___________________________________________________________________ 
PROPERTY1:  VALUE1_2 
PROPERTY222: VALUE2_2 
PROPERTY33: VALUE3_2 
PROPERTY4444: VALUE4_2 
PROPERTY55: VALUE5_2 

Description1: Some text goes here 
Description2: Some text goes here 

Ich möchte ein anderes Element in die Datei hinzufügen, sed oder awk mit:

sed -i -r "\$a$PROPERTY1:  VALUE1_3" file.txt 
sed -i -r "\$a$PROPERTY2222:  VALUE2_3" file.txt 

So sieht usw. mein nächster Punkt wie folgt aus:

___________________________________________________________________ 
ITEM 3 
___________________________________________________________________ 
PROPERTY1:  VALUE1_3 
PROPERTY222:  VALUE2_3 
PROPERTY33:  VALUE3_3 
PROPERTY4444:  VALUE4_3 
PROPERTY55:  VALUE5_3 

Description1: Some text goes here 
Description2: Some text goes here 

Die Säule Werte gezackt ist. Wie richte ich meine Werte wie bei früheren Elementen nach links aus? Ich kann hier 2 Lösungen sehen:

  1. Zum Ausrichten der Werte beim Einfügen in die Datei.
  2. Um die Werte in die Datei einzufügen, wie ich es getan habe und sie als nächstes auszurichten.

Der Befehl

sed -i -r "s|.*:.*|&|g" file.txt 

Fänge die Eigenschaften und Werte, die ich ausrichten wollen, aber ich habe nicht in der Lage gewesen, sie richtig auszurichten, dh

awk '/^.*:.*$/{ printf "%-40s %-70s\n", $1, $2 }' file.txt 

Es druckt die Datei , aber es enthält die Beschreibung Werte und Tags, schneidet die Werte, wenn sie Leerzeichen oder Bindestriche enthalten. Es ist nur ein großes Durcheinander.

Ich habe mehr Befehle basierend auf was ich auf Stack Overflow und einigen Blogs gefunden habe, aber nichts tut was ich brauche.

Hinweis: Die Werte der Beschreibungsvariablen sind nicht gezackt - dies liegt daran, dass ich sie in einer separaten Weise in die Datei schreibe.

Was ist falsch an meinen Befehlen? Wie erreiche ich, was ich brauche?

+0

Während dies mit sed/awk lösbar ist, könnte es mit mächtigeren Tools einfacher zu lösen sein. Haben Sie überlegt, eine vollwertige Programmiersprache (z. B. Perl, Ruby, C++) mit geeigneten Datenstrukturen zu verwenden, um Ihr Problem zu lösen? – Heinrich

+0

@Heinrich, ich würde es vermeiden, vollwertige Programmiersprachen zu verwenden, weil ich ein fast vollständiges Skript in bash habe, das genau das tut, was ich will und das ist das einzige Problem damit. Ich möchte die Benutzer meines Skripts nicht zwingen, Compiler oder Interpreter für verschiedene Sprachen zu installieren, aufgrund dieses (nicht so ernsthaften) Problems. – user2738748

Antwort

1

Wenn Ihre Datei ohne Reiter ist, versuchen Sie dies:

sed -r 's/: +/:\t/' file.txt | expand -20 

Wenn dies funktioniert, die Ausgabe in eine tmpfile umleiten und die tmpfile zu file.txt bewegen.

0

Sie \ t nutzen könnten Registerkarten einfügen (statt Leerzeichen, weshalb man 'zackig' Werte erhalten)

statt

sed -i -r "\$a$PROPERTY1:  VALUE1_3" file.txt 

Verwendung

sed -i -r "\$a$PROPERTY1:\t\tVALUE1_3" file.txt 
+1

Die Verwendung von Tabs kann immer noch zu einer gezackten Ausrichtung führen, wenn die Länge eines Schlüssels z. zwei Tabs (plus einige Leerzeichen) lang und ein weiterer Key ist drei Tabs (wieder, plus ein paar Leerzeichen) lang. – Heinrich

+0

@ M.B. Es spielt keine Rolle, ob ich Tabulatoren oder Leerzeichen einfüge. Die Namen der Eigenschaften unterscheiden sich in der Länge, daher werde ich immer gezackte Werte erhalten. – user2738748

1

Sie verwenden gensub und durchdachte Feldtrenner, um sich darum zu kümmern:

for i in {1..5}; do 
    echo $((10 ** i)): $i; 
done | awk -F ':::' '/^[^:]+:.+/{ 
    $0 = gensub(/: +/, ":::", $0); 
    key=($1 ":"); 
    printf "%-40s %s\n", key, $2; 
}' 

Der relevante Teil ist, wo wir ": +" für nur ":::" austauschen und dann einen printf machen, um es wieder zusammen zu bringen.

+0

Sie rufen gensub() falsch auf (Sie füllen das Feld "Wie viele Ersetzungen" mit "$ 0"), Sie brauchen keine Parens um die String-Verkettung, Sie brauchen keine abschließenden Zeilenumbrüche, das kann ich mir nicht vorstellen Was ändert man ': +' zu ':::' und setzt FS auf ':::' anstatt nur FS auf ': +' zu setzen (wer sagt '':' existiert nicht in a VALUE?) Oder nur mit ein paar sub() s. Oh, und du solltest erwähnen, dass es wegen der Verwendung von 'gensub()' gawk-spezifisch ist. –

0

Alles, was Sie tun müssen, ist die vorhandene Vertiefung erinnern, wenn die neue Zeile eingefügt, zB:

echo 'PROPERTY732: VALUE9_8_7' | 
awk -v prop="PROPERTY1" -v val="VALUE1_3" ' 
     match($0,/^PROPERTY[^[:space:]]+[[:space:]]+/) { wid=RLENGTH } 
     { print } 
     END { printf "%-*s%s\n", wid, prop":", val } 
    ' 
PROPERTY732: VALUE9_8_7 
PROPERTY1:  VALUE1_3 

aber es ist nicht klar, dass die Zugabe von 1 Zeile zu einem Zeitpunkt sinnvoll ist oder wo alle anderen Text Das Hinzufügen kommt von.

Das obige funktioniert mit jedem awk auf jedem UNIX-System.

Wenn Ihre "Eigenschaften" nicht mit dem Wort PROPERTY beginnen, dann müssen Sie nur Ihre Frage bearbeiten, um realistischere Eingabe/Ausgabe zu zeigen und uns zeigen, wie man eine PROPERTY-Zeile von einer Description-Zeile unterscheidet Auch hier wird die Lösung mit awk trivial sein.

Verwandte Themen