En python
re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke )
Pour diviser un nombre par des triplets, par exemple:
echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",", sys.stdin.read());'
123,456,789
Comment faire la même chose avec bash / awk?
bash
shell-script
awk
string
utilisateur2496
la source
la source
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g"){sub(",$",""); print}'
sed
ne fonctionne que si le nombre est exactement 9 chiffres. Leprintf
ne fonctionne pas sur zsh. Ainsi, la deuxièmesed
réponse est probablement la meilleure.echo 123456789 | awk '{printf ("%'\''d\n", $0)}'
(ce qui ne fonctionne évidemment pas toujours sous Linux!?, Mais fonctionne parfaitement sous AIX et Solaris)bash
de »printf
les supports à peu près tout ce que vous pouvez faire dans laprintf
fonction Cprintf
de coreutils fera de mêmela source
zsh
aussi, post mis à jour ici .vsnprintf
. Sur un système GNU / Linux, glibc semble l’avoir supporté depuis au moins 1995.export LC_NUMERIC="en_US"
si vous voulez forcer les virgules.locale -a
. Je devais utiliseren_US.utf8
Vous pouvez utiliser numfmt:
Ou:
Notez que numfmt n'est pas un utilitaire POSIX, il fait partie de GNU coreutils.
la source
-d, --grouping
puisque les doubles tirets ont besoin d'options longues?--g
fonctionne bien pour moi au lieu de--grouping
, à savoirnumfmt --g 1234567890
etnumfmt --grouping 1234567890
faire la même chose. C'est un petit utilitaire très utile.produit:
Ceci est accompli en scindant la chaîne de chiffres en 2 groupes, le groupe de droite avec 3 chiffres, le groupe de gauche avec le reste, mais au moins un chiffre. Ensuite, tout est remplacé par les 2 groupes, séparés par une virgule. Cela continue jusqu'à ce que la substitution échoue. Les options "wpe" sont destinées à la liste des erreurs, renferment l'instruction dans une boucle avec une impression automatique et prennent l'argument suivant comme "programme" perl (voir la commande perldoc perlrun pour plus de détails).
Meilleurs voeux ... A bientôt, drl
la source
BASH
/AWK
alternative afin qu'il ne l'ait peut-être pas utiliséPERL
auparavant. Dans tous les cas, il est préférable d’expliquer ce que la commande fait, en particulier pour les doublures.Avec quelques
awk
implémentations:"%'"'"'d\n"
est:"%
(devis simple) (devis double) (devis simple) (devis double) (devis simple) d \ n"
Cela utilisera le séparateur de milliers configuré pour vos paramètres régionaux (généralement
,
en paramètres régionaux anglais, espace en français,.
en espagnol / allemand ...). Identique à celle renvoyée parlocale thousands_sep
la source
Pour moi, un cas d'utilisation courant consiste à modifier la sortie d'un pipeline de commandes afin que les nombres décimaux soient imprimés avec des séparateurs de milliers. Plutôt que d'écrire une fonction ou un script, je préfère utiliser une technique que je peux personnaliser à la volée pour toute sortie d'un pipeline Unix.
J'ai trouvé
printf
(fourni par Awk) le moyen le plus flexible et le plus mémorable d'accomplir cela. Le caractère apostrophe / guillemet simple est spécifié par POSIX en tant que modificateur pour formater les nombres décimaux et présente l'avantage de tenir compte des paramètres régionaux, de sorte qu'il n'est pas limité à l'utilisation de virgules.Lors de l'exécution de commandes Awk à partir d'un shell Unix, il peut être difficile d'entrer un caractère entre guillemets dans une chaîne délimitée par des guillemets simples (pour éviter le développement de shell dans les variables de position, par exemple
$1
). Dans ce cas, le moyen le plus lisible et le plus fiable pour saisir le caractère guillemet simple est de le saisir sous forme de séquence d'échappement octale (commençant par\0
).Exemple:
Sortie simulée d'un pipeline indiquant les répertoires utilisant le plus d'espace disque:
D'autres solutions sont énumérées dans Comment échapper à une citation unique dans awk .
Remarque: comme indiqué dans Imprimer un seul devis , il est recommandé d'éviter l'utilisation de séquences d'échappement hexadécimales, car elles ne fonctionnent pas de manière fiable sur différents systèmes.
la source
\047
.awk
etbash
avoir de bonnes solutions intégrées, basées surprintf
, comme décrit dans les autres réponses. Mais d' abord,sed
.Pour
sed
, nous devons le faire "manuellement". La règle générale est que si vous avez quatre chiffres consécutifs, suivis d'un non-chiffre (ou fin de ligne), une virgule doit être insérée entre le premier et le deuxième chiffre.Par exemple,
imprimera
Nous devons évidemment continuer à répéter le processus, afin de continuer à ajouter suffisamment de virgules.
Dans
sed
, lat
commande spécifie une étiquette à laquelle accéder si la dernières///
commande a réussi. Je définis donc une étiquette avec:restart
, afin qu’elle revienne en arrière.Voici une démo bash (sur ideone ) qui fonctionne avec n'importe quel nombre de chiffres:
la source
la source
Si vous regardez de grands nombres, je n’ai pas pu appliquer les solutions ci-dessus. Par exemple, obtenons un très grand nombre:
$ echo 2^512 |bc -l|tr -d -c [0-9] 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
Notez que j’ai besoin
tr
de supprimer la barre oblique inverse de la sortie ligne à barre oblique inverse. Ce nombre est trop gros pour être traité comme un nombre à virgule flottante ou fixe dans awk, et je ne souhaite même pas créer une expression rationnelle suffisamment grande pour prendre en compte tous les chiffres de sed. Je peux plutôt l'inverser et insérer des virgules entre des groupes de trois chiffres, puis l'annuler: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
la source
awk: run time error: improper conversion(number 1) in printf("%'d
.la source
sed 's/^,//g'
.Je souhaitais également que la partie après le séparateur décimal soit correctement séparée / espacée. J'ai donc écrit ce script sed qui utilise certaines variables du shell pour s’adapter aux préférences régionales et personnelles. Il prend également en compte différentes conventions pour le nombre de chiffres regroupés :
la source
Une solution
bash
/awk
(à la demande) qui fonctionne quelle que soit la longueur du nombre et utilise,
quels que soient les paramètres régionauxthousands_sep
, et où que les nombres soient en entrée, évitant d’ajouter le séparateur de milliers après1.12345
:Donne:
Avec de
awk
telles implémentationsmawk
ne supportant pas les opérateurs d'intervalle regex, changez l'expression rationnelle en/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
la source