W python
re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke )
Aby podzielić liczbę na trojaczki, np .:
echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",", sys.stdin.read());'
123,456,789
Jak zrobić to samo z bash / awk?
bash
shell-script
awk
string
użytkownik2496
źródło
źródło
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g"){sub(",$",""); print}'
sed
działa tylko wtedy, gdy liczba składa się dokładnie z 9 cyfr.printf
Nie działa na zsh. Zatem drugased
odpowiedź jest prawdopodobnie najlepsza.echo 123456789 | awk '{printf ("%'\''d\n", $0)}'
(co najwyraźniej nie zawsze działa w systemie Linux!?, Ale działa dobrze w systemach AIX i Solaris)bash
„sprintf
obsługuje prawie wszystko, co można zrobić wprintf
funkcji Cprintf
od coreutils zrobi to samoźródło
zsh
również w zaktualizowanym poście tutaj .vsnprintf
. W systemie GNU / Linux wydaje się, że glibc obsługuje go od co najmniej 1995 roku.export LC_NUMERIC="en_US"
jeśli chcesz wymusić przecinki.locale -a
. Musiałem użyćen_US.utf8
Możesz użyć numfmt:
Lub:
Zauważ, że numfmt nie jest narzędziem POSIX, jest częścią jądra GNU.
źródło
-d, --grouping
ponieważ podwójne dzielenie wyrazów wymaga długich opcji?--g
działa dobrze dla mnie zamiast--grouping
, tj.numfmt --g 1234567890
inumfmt --grouping 1234567890
zrobić to samo. Jest to bardzo przydatne małe narzędzie.produkuje:
Odbywa się to poprzez podzielenie ciągu cyfr na 2 grupy, prawą grupę z 3 cyframi, lewą grupę z resztą, ale co najmniej jedną cyfrę. Następnie wszystko jest zastępowane przez 2 grupy, oddzielone przecinkiem. Trwa to do momentu niepowodzenia podstawienia. Opcje „wpe” służą do wyświetlania listy błędów, zawierają instrukcję w pętli z automatycznym drukowaniem i przyjmują następny argument jako „program” perla (szczegóły w poleceniu perldoc perlrun).
Najlepsze życzenia ... Pozdrawiam, drl
źródło
BASH
/AWK
alternatywę, więc może nie używałPERL
wcześniej. W każdym razie najlepiej wyjaśnić, co robi polecenie - szczególnie w przypadku jedno-liniowych.Z niektórymi
awk
implementacjami:"%'"'"'d\n"
to:"%
(pojedynczy cytat) (podwójny cytat) (pojedynczy cytat) (podwójny cytat) (pojedynczy cytat) d \ n"
To wykorzysta skonfigurowany separator tysięcy dla twoich ustawień regionalnych (zazwyczaj
,
w języku angielskim, spacja w języku francuskim,.
w języku hiszpańskim / niemieckim ...). Taki sam jak zwrócony przezlocale thousands_sep
źródło
Częstym przypadkiem użycia jest dla mnie modyfikacja wyjścia potoku poleceń, tak aby liczby dziesiętne były drukowane z tysiącem separatorów. Zamiast pisać funkcję lub skrypt, wolę używać techniki, którą mogę dostosować w locie dla dowolnego wyjścia z potoku Unix.
printf
Przekonałem się (zapewniony przez Awk), że jest to najbardziej elastyczny i niezapomniany sposób na osiągnięcie tego. Znak apostrofu / pojedynczego cudzysłowu jest określany przez POSIX jako modyfikator formatowania liczb dziesiętnych i ma tę zaletę, że rozpoznaje ustawienia regionalne, więc nie ogranicza się do używania przecinków.Podczas uruchamiania poleceń Awk z powłoki uniksowej mogą wystąpić trudności z wprowadzeniem znaku pojedynczego cudzysłowu w ciągu ograniczonym pojedynczymi cudzysłowami (np. W celu uniknięcia rozszerzenia powłoki przez zmienne pozycyjne
$1
). W tym przypadku uważam, że najbardziej czytelnym i niezawodnym sposobem wprowadzenia znaku pojedynczego cudzysłowu jest wprowadzenie go w postaci ósemkowej sekwencji ucieczki (zaczynającej się od\0
).Przykład:
Symulowane wyjście potoku pokazujące, które katalogi zajmują najwięcej miejsca na dysku:
Inne rozwiązania są wymienione w temacie Jak uniknąć pojedynczego cytatu w awk .
Uwaga: zgodnie z ostrzeżeniem w Print a Single Quote , zaleca się unikanie używania szesnastkowych sekwencji ucieczki, ponieważ nie działają one niezawodnie w różnych systemach.
źródło
\047
.awk
ibash
mają dobre wbudowane rozwiązania oparte naprintf
, jak opisano w innych odpowiedziach. Ale najpierwsed
.Bo
sed
musimy to zrobić „ręcznie”. Ogólna zasada jest taka, że jeśli masz cztery kolejne cyfry, po których następuje cyfra (lub koniec linii), to pomiędzy pierwszą i drugą cyfrą należy wstawić przecinek.Na przykład,
wydrukuje
Oczywiście musimy nadal powtarzać ten proces, aby dodawać wystarczającą liczbę przecinków.
W
sed
polut
polecenie określa etykietę, która zostanie przeskoczona, jeśli ostatnies///
polecenie zakończyło się powodzeniem. Dlatego definiuję etykietę za pomocą:restart
, aby odskakiwała.Oto demo bash (na ideone ), które działa z dowolną liczbą cyfr:
źródło
źródło
Jeśli patrzysz na DUŻE liczby, nie byłem w stanie sprawić, by powyższe rozwiązania działały. Na przykład, uzyskajmy naprawdę dużą liczbę:
$ echo 2^512 |bc -l|tr -d -c [0-9] 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
Uwaga: Potrzebuję
tr
usunąć wyjście nowego wiersza odwrotnego ukośnika z bc. Ta liczba jest zbyt duża, aby traktować ją jako liczbę zmiennoprzecinkową lub stałą liczbę bitów w awk, i nawet nie chcę budować wyrażenia regularnego wystarczająco dużego, aby uwzględnić wszystkie cyfry w sed. Mogę raczej odwrócić i umieścić przecinki między grupami po trzy cyfry, a następnie cofnąć: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
źródło
awk: run time error: improper conversion(number 1) in printf("%'d
.źródło
sed 's/^,//g'
.Chciałem również mieć udział po tym separatorem dziesiętnym prawidłowo oddzielone / rozstawione, dlatego napisałem ten SED-skrypt, który wykorzystuje pewne zmienne powłoki, aby dostosować się do preferencji regionalnych i osobistych. Uwzględnia także różne konwencje dotyczące liczby cyfr zgrupowanych razem :
źródło
Rozwiązanie A
bash
/awk
(zgodnie z żądaniem), które działa niezależnie od długości liczby i używa,
niezależnie od ustawienia ustawień regionalnychthousands_sep
oraz wszędzie tam, gdzie liczby są na wejściu i pozwala uniknąć dodawania separatora tysięcy po1.12345
:Daje:
W przypadku
awk
takich implementacjimawk
, które nie obsługują operatorów wyrażeń regularnych, zmień wyrażenie regularne na/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
źródło