In Python
re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke )
Um eine Zahl durch Drillinge zu teilen, zB:
echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",", sys.stdin.read());'
123,456,789
Wie mache ich dasselbe mit bash / awk?
bash
shell-script
awk
string
user2496
quelle
quelle
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g"){sub(",$",""); print}'
sed
funktioniert erstens nur, wenn die Nummer genau 9 Stellen hat. Dasprintf
funktioniert nicht auf zsh. Somit ist die zweitesed
Antwort wahrscheinlich die beste.echo 123456789 | awk '{printf ("%'\''d\n", $0)}'
(was offensichtlich nicht immer unter Linux funktioniert!?, Aber unter AIX und Solaris funktioniert es einwandfrei)bash
‚sprintf
unterstützt so ziemlich alles , was Sie können in der tunprintf
C - Funktionprintf
von Coreutils wird das gleiche tunquelle
zsh
aktualisierten Beitrag unterstützt .vsnprintf
. Auf einem GNU / Linux-System scheint glibc es seit mindestens 1995 unterstützt zu haben.export LC_NUMERIC="en_US"
wenn Sie Kommas erzwingen möchten.locale -a
. Ich mussteen_US.utf8
Sie können numfmt verwenden:
Oder:
Beachten Sie, dass numfmt kein POSIX-Dienstprogramm ist, sondern Teil von GNU coreutils.
quelle
-d, --grouping
da doppelte Silbentrennungen lange Optionen erfordern?--g
funktioniert gut für mich statt--grouping
, dhnumfmt --g 1234567890
undnumfmt --grouping 1234567890
mache das gleiche. Es ist ein sehr nützliches kleines Hilfsprogramm.produziert:
Dies wird erreicht, indem die Ziffernfolge in 2 Gruppen aufgeteilt wird, die rechte Gruppe mit 3 Ziffern, die linke Gruppe mit allen verbleibenden Ziffern, aber mindestens einer Ziffer. Dann wird alles durch die 2 durch Komma getrennten Gruppen ersetzt. Dies wird fortgesetzt, bis die Substitution fehlschlägt. Die Optionen "wpe" dienen zur Fehlerauflistung, schließen die Anweisung in einer Schleife mit einem automatischen Ausdruck ein und nehmen das nächste Argument als Perl "program" (Details siehe Befehl perldoc perlrun).
Beste Wünsche ... Prost, drl
quelle
BASH
/AWK
Alternative gefragt , die er möglicherweise noch nicht verwendetPERL
hat. In jedem Fall ist es am besten zu erklären, was der Befehl bewirkt - insbesondere für Einzeiler.Mit einigen
awk
Implementierungen:"%'"'"'d\n"
ist:"%
(einfaches Anführungszeichen) (doppeltes Anführungszeichen) (einfaches Anführungszeichen) (doppeltes Anführungszeichen) d \ n"
Dabei wird das konfigurierte Tausendertrennzeichen für Ihr Gebietsschema verwendet (normalerweise
,
in englischer Sprache, Leerzeichen in Französisch,.
in Spanisch / Deutsch ...). Gleich wie von zurückgegebenlocale thousands_sep
quelle
Ein häufiger Anwendungsfall für mich ist es, die Ausgabe einer Befehlspipeline so zu ändern, dass Dezimalzahlen mit Tausendertrennzeichen gedruckt werden. Anstatt eine Funktion oder ein Skript zu schreiben, bevorzuge ich eine Technik, die ich spontan für jede Ausgabe aus einer Unix-Pipeline anpassen kann .
Ich habe festgestellt
printf
(bereitgestellt von Awk), dass dies der flexibelste und einprägsamste Weg ist, dies zu erreichen. Das Apostroph- / Anführungszeichen wird von POSIX angegeben als Modifikator zum Formatieren von Dezimalzahlen angegeben und hat den Vorteil, dass es das Gebietsschema berücksichtigt und nicht auf die Verwendung von Kommazeichen beschränkt ist.Wenn Sie Awk-Befehle in einer Unix-Shell ausführen, kann es schwierig sein, ein einfaches Anführungszeichen in eine durch einfache Anführungszeichen begrenzte Zeichenfolge einzugeben (um die Shell-Erweiterung von Positionsvariablen zu vermeiden, z
$1
. B. ). In diesem Fall finde ich die lesbarste und zuverlässigste Möglichkeit, ein einfaches Anführungszeichen einzugeben, darin, es als oktale Escape-Sequenz (beginnend mit\0
) einzugeben .Beispiel:
Simulierte Ausgabe einer Pipeline, aus der hervorgeht, welche Verzeichnisse den meisten Speicherplatz belegen:
Andere Lösungen sind in aufgeführt So vermeiden Sie ein einfaches Anführungszeichen in awk .
Hinweis: wie gegen warnte in Apostroph drucken , es wird empfohlen , die Verwendung von hexadezimalen Escape - Sequenzen zu vermeiden , da sie über verschiedene Systeme nicht zuverlässig arbeiten.
quelle
\047
.awk
undbash
haben gute integrierte Lösungen, basierend aufprintf
, wie in den anderen Antworten beschrieben. Aber zuerstsed
.Zum
sed
müssen wir es "manuell" tun. Die allgemeine Regel lautet: Wenn Sie vier aufeinanderfolgende Ziffern gefolgt von einer Nicht-Ziffer (oder einem Zeilenende) haben, sollte ein Komma zwischen der ersten und der zweiten Ziffer eingefügt werden.Beispielsweise,
wird gedruckt
Wir müssen dann natürlich den Vorgang wiederholen, um immer genug Kommas hinzuzufügen.
In
sed
gibt dert
Befehl eine Bezeichnung an, zu der gesprungen wird, wenn der letztes///
Befehl erfolgreich war. Ich definiere daher ein Label mit:restart
, damit es zurückspringt.Hier ist eine Bash-Demo (auf Ideone ), die mit einer beliebigen Anzahl von Ziffern funktioniert:
quelle
quelle
Wenn Sie sich GROSSE Zahlen ansehen, konnte ich die obigen Lösungen nicht zum Laufen bringen. Lassen Sie uns zum Beispiel eine wirklich große Zahl erhalten:
$ echo 2^512 |bc -l|tr -d -c [0-9] 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
Hinweis Ich benötige das
tr
, um die Ausgabe von Backslash Newline von bc zu entfernen. Diese Zahl ist zu groß, um sie in awk als Float- oder feste Bitnummer zu behandeln, und ich möchte nicht einmal einen regulären Ausdruck erstellen, der groß genug ist, um alle Ziffern in sed zu berücksichtigen. Eher kann ich es umkehren und Kommas zwischen Gruppen von drei Ziffern setzen, dann es wieder rückgängig machen:echo 2^512 |bc -l|tr -d -c [0-9] |rev |sed -e 's/\([0-9][0-9][0-9]\)/\1,/g' |rev 13,407,807,929,942,597,099,574,024,998,205,846,127,479,365,820,592,393,377,723,561,443,721,764,030,073,546,976,801,874,298,166,903,427,690,031,858,186,486,050,853,753,882,811,946,569,946,433,649,006,084,096
quelle
awk: run time error: improper conversion(number 1) in printf("%'d
.quelle
sed 's/^,//g'
.Ich wollte auch, dass der Teil nach dem Dezimaltrennzeichen richtig getrennt / beabstandet ist, deshalb habe ich dieses sed-Skript geschrieben, das einige Shell-Variablen verwendet, um regionale und persönliche Präferenzen anzupassen. Dabei werden auch unterschiedliche Konventionen für die Anzahl der zusammen gruppierten Ziffern berücksichtigt :
quelle
A
bash
/awk
(nach Wunsch) Lösung , die unabhängig von der Länge der Anzahl und Anwendungen arbeitet,
unabhängig von der Gebietsschema -thousands_sep
Einstellung, und überall dort , wo die Zahlen sind im Ein- und vermeidet Zugabe des Tausendertrennzeichen nach in1.12345
:Gibt:
Mit
awk
Implementierungen wiemawk
das nicht die Intervall regex Operatoren unterstützen, ändern Sie den regulären Ausdruck/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
quelle