Ich habe Probleme, meine sed-Syntax zu ändern, um einem numerischen Organisationsschema eine unterschiedliche Anzahl führender Nullen hinzuzufügen. Die Zeichenfolgen, mit denen ich arbeite, sehen wie folgt aus
1.1.1.1,Some Text Here
Nutzung der sed-Syntax
sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"
Ich kann die Antwort auslösen
01.01.01.01,Some Text Here
Was ich jedoch suche, ist etwas, das bis zu 2 Stellen in den Feldern 2 und 3 und 3 Stellen in Feld 4 auf Null gesetzt werden kann, damit alle Elemente eine Standardlänge von [0-9] haben. [0-9] { 2}. [0-9] {2}. [0-9] {3}
1.01.01.001,Some Text Here
Für mein Leben kann ich nicht einmal herausfinden, wie ich die Grenze so ändern kann, dass sie die Parameter enthält, die erforderlich sind, um nach einem Punkt nur noch Zahlen zu erfassen. Ich denke, es hat etwas mit der Verwendung von \ b zu tun, von dem ich verstehe, dass es an einer Wortgrenze mit Null Zeichen übereinstimmt, aber ich verstehe nicht, warum meine Versuche, der Übereinstimmung einen Punkt hinzuzufügen, wie folgt fehlschlagen:
sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang
sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:
1.01.01.1,Some Text Here
Außerdem erwarte ich zusätzliche Probleme, wenn die Anweisung Text enthält wie:
1.1.1.1,Some Number 1 Here
Es ist eine ausgemachte Sache, dass ich sed und all seine Komplexität wirklich lernen muss. Ich arbeite daran, aber erwarte, dass diese spezielle Aussage mir noch eine Weile Ärger bereiten wird. Jede Hilfe wäre sehr dankbar.
EDIT: Ich habe einen Weg gefunden ... Diese Aussage scheint das zu tun, wonach ich suche, aber es muss einen eleganteren Weg geben, dies zu tun.
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Auch syntaktisch verursacht dies Probleme, wenn ein ähnliches Zahlenformat im Text erscheint ... ähnlich wie:
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3
In diesem Fall führt dies zu:
1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03
Gelöst Vielen Dank für Ihre Hilfe hier. Ich habe das Problem zunächst mit der Antwort gelöst, die ich unten akzeptiert habe. Ich habe das Gefühl, dass die Lösung als Teil einer größeren Lösung, die die folgende Sortierung nutzt, in Python verschoben wurde:
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
s=sorted(reader, key=getPaddedKey)
quelle
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Ich würde jedoch gerne wissen, ob es einen eleganteren Ansatz gibt.printf
(oder einprintf
Anruf innerhalb von Awk) ist möglicherweise einfacher.Antworten:
Verwendung:
leading_zero.sh input.txt
Erläuterung:
input.txt
output.txt
quelle
perl
Version keine Backslashes.Bash kann damit umgehen. Es wird allerdings viel langsamer als Perl sein:
quelle
printf
, das sinnvolle Werkzeug. (Awk hatprintf
auch und ist besser alsbash
für die Textverarbeitung konzipiert.) Siehe auch Warum wird die Verwendung einer Shell-Schleife zum Verarbeiten von Text als schlechte Praxis angesehen?Sie haben nicht speziell nach einer
perl
Lösung gefragt , aber hier ist trotzdem eine. Persönlich denke ich, dass dies etwas einfacher zu lesen ist, insbesondere wenn es in mehrere Zeilen unterteilt ist.Zuerst hier ist der Einzeiler:
Seine Ergebnisse:
Und hier ist das
perl
Skript ausgebrochen und kommentiert (das-n
Flag setzt eine implizitewhile read; do ... done
Schleife um den Code):quelle
awk
würde auch funktionieren - das gleiche Prinzip mitprintf
Hier ist ein möglicher Ansatz:
sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
Beispiele
Arbeiten Sie auch mit dieser Zeichenfolge:
... und diese Zeichenfolge:
quelle
Erläuterung:
Die hier verwendete Methode besteht darin, die Nachbarschaften der Numerik zu betrachten und darauf basierend Maßnahmen zu ergreifen. Die 2. und 3. Zahl sehen also auf beiden Seiten einen Punkt, während die 4. Zahl links einen Punkt und rechts ein Komma sieht.
Die $ 1 wird gesetzt, wenn der Regex den Pfad der 2. oder 3. Zahl nimmt und dementsprechend die Präzisionsauffüllung 2 ist. OTOH, für die 4. Zahl ist die Auffüllung 3.
% cat file.txt
Ergebnisse:
quelle