Вычесть большое число в баш

Мне нравится анализировать HTML с регулярными выражениями. Я не пытаюсь разбирать идиот HTML, который намеренно нарушен. Этот код является моим основным парсером (версия Perl):

$_ = join "",; tr/\n\r \t/ /s; s//>\n/g; s/\n ?\n/\n/g;
s/^ ?\n//s; s/ $//s; print

Он называется htmlsplit, разбивает HTML на строки, с одним тегом или фрагментом текста в каждой строке. Затем линии могут быть обработаны другими текстовыми инструментами и сценариями, такими как grep , sed , Perl и т. Д. Я даже не шучу :) Наслаждайтесь.

Достаточно просто переписать мой скрипт Perl-all-first Perl в приятную поточную вещь, если вы хотите обрабатывать огромные веб-страницы. Но это действительно не обязательно.

Бьюсь об заклад, я заберусь для этого.

HTML Split


Против моего ожидая, что это получило некоторые upvotes, поэтому я предлагаю несколько правильных выражений:

/(<.*?>|[^<]+)\s*/g    # get tags and text
/(\w+)="(.*?)"/g       # get attibutes

Они хороши для XML / XHTML.

С небольшими вариациями он может справиться с беспорядочным HTML ... или сначала конвертировать HTML -> XHTML.


Лучший способ записи регулярных выражений - в Lex / Yacc стиль, а не непрозрачные однострочные или прокомментированные многострочные чудовища. Я не делал этого здесь; эти им едва ли нужны.

3
задан Tanktalus 17 January 2019 в 16:11
поделиться

4 ответа

Раздел ARITHMETIC EVALUATION руководства bash объясняет, почему вы получаете этот результат с помощью $((...)):

Оценка выполняется в целых числах фиксированной ширины без проверки на переполнение

]

Возможно, вы сможете использовать expr (в зависимости от параметров времени компиляции, проверьте комментарий @Benjamin W ), но вам нужны пробелы между оператором и его операндами :

$ expr 1805334111369276485744644020321551471447190030955050085289 - 3369574570478873127315415525946742317481702644901195284480
-1564240459109596641570771505625190846034512613946145199191

Как @PesaThe упоминает, что вы также можете использовать bc, одна из его основных функций, способная обрабатывать произвольную точность арифметики:

bc <<< "1805334111369276485744644020321551471447190030955050085289 - 3369574570478873127315415525946742317481702644901195284480"
-1564240459109596641570771505625190846034512613946145199191
0
ответ дан Aaron 17 January 2019 в 16:11
поделиться

Если вы любите приключения, вы можете использовать старый добрый dc (настольный калькулятор, симпатичный калькулятор RPN):

dc <<< "1805334111369276485744644020321551471447190030955050085289 3369574570478873127315415525946742317481702644901195284480 - p"

Ответ: -1564240459109596641570771505625190846034512613946145199191

0
ответ дан gniourf_gniourf 17 January 2019 в 16:11
поделиться

Вы можете использовать Perl

$ perl -le ' BEGIN { use Math::BigInt; my $x=Math::BigInt->new("1805334111369276485744644020321551471447190030955050085289"); my $y=Math::BigInt->new("3369574570478873127315415525946742317481702644901195284480"); print $x->bsub($y) } '
-1564240459109596641570771505625190846034512613946145199191
$ perl -le ' BEGIN { use Math::BigInt; my $x=Math::BigInt->new("1805334111369276485744644020321551471447190030955050085289"); my $y=Math::BigInt->new("3369574570478873127315415525946742317481702644901195284480"); printf("%g\n",$x->bsub($y)) } '
-1.56424e+57
$

. Если вы хотите передать эхо-вывод в Perl, тогда

$ echo "1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480" | perl -ne ' BEGIN { use Math::BigInt } /(\d+)-(\d+)/; $x=Math::BigInt->new($1); $y=Math::BigInt->new($2); printf("%g\n",$x->bsub($y)) '
-1.56424e+57
$

Как @Pesa. Упомянутое, вы можете использовать bc также

.
$ bc <<< "1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480"
-1564240459109596641570771505625190846034512613946145199191
$
0
ответ дан stack0114106 17 January 2019 в 16:11
поделиться

Mac OSX awk также может обрабатывать большие числа:

awk 'BEGIN{print 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'

-1.56424045910959651912822682029e+57

Или с помощью printf:

awk 'BEGIN{printf "%.5e\n", 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'

[1111 ]

-1.56424e+57

С другой стороны, GNU awk требуется переключатель -M для поддержки больших чисел, поэтому используйте:

gawk -M 'BEGIN{print 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'
0
ответ дан anubhava 17 January 2019 в 16:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: