для строки в $(cat file.txt)
будет перебирать каждый глобус в файле один за другим.Ввод, отправленный в awk
, будет иметь только один столбец ввода, поэтому $2
всегда будет нулевым.
Использование awk:
awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
TXR awk macro : мы действительно можем сделать это как типизированные операции: получить данные в виде значений с плавающей запятой, уменьшить их до ближайшего целого числа, умножить на сотню, преобразовать в целое число.
Однако давайте сделаем паузу и поразмышляем, что это может быть плохой идеей, если значения настолько велики, что их нельзя усечь до ближайшего целого числа; выполнение этого текста будет правильным для произвольно больших значений.
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf tofloat floor toint (* 100))))'
(4567.99, 123.45, junk 3.1415, 1.0 ...) x
456700 12300 300 100
Переменная ft
- это новая функция; классический Awk не имеет аналогов. В то время как fs
похож на FS
(разделитель полей), ft
означает «маркер поля»: он определяет положительное регулярное выражение, которое распознает и извлекает поля, игнорируя несоответствия. вещи между ними.
По иронии судьбы
ft
может напрямую выражать семантику разделителя полей по умолчанию в Awk: обрезка начальных и конечных символов новой строки и пробелов из записи и разделение на одну или несколько новых строк или пробелов. Это в точности эквивалентно простому положительному распознаванию полей как токенов, состоящих из не пробелов! Если бы в Awk была переменнаяFT
, ему не понадобился бы специальный прием, который применяется, когдаFS
равно одному пробелу; по умолчаниюFS
не установлен, аFK
установлен в регулярное выражение[\ t \ n] +
.
Мы используем простой ft
, который распознает цифры, обязательные десятичные и обязательные цифры. Без ведущего знака, без дополнительных частей.
Макрос mf
(«поля карты») помещает каждое поле в конвейер операций. Во-первых, функция tofloat
преобразует строки в числа с плавающей запятой. Затем floor
усекается до ближайшего целого числа в сторону отрицательной бесконечности. toint
возвращает нас к inger, а (* 100)
обозначает частичное применение *
к 100
: функция, которая принимает дополнительные аргументы и умножает 100
на их произведение. Этот частичный синтаксис приложения следует из того факта, что аргументы mf
неявно обрабатываются как синтаксис op
: явный частичный оператор приложения TXR Lisp.
Поскольку mf
возвращает результат, отличный от nil
, запускается действие по умолчанию (prn)
для печати обновленного rec
, который воссоздается путем связывания обновленных полей со значениями по умолчанию of
, состоящими из одного символа пробела, и выводом или
, которые по умолчанию являются символом новой строки.
Вот способ сделать это численно, не полагаясь на математику с плавающей запятой. В принципе, мы можем извлечь поля, используя то же регулярное выражение, но затем удалить точку, пока они все еще являются текстом. Затем перейдите к целому числу и используйте усечение целочисленного деления и умножения:
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf (remq #\.) toint (trunc @1 100) (* 100))))'
Поскольку целые числа могут быть сколь угодно большими в этом языке, это решение не страдает от проблем, связанных с большими числами, но минимизирует обработку текста.
awk '{gsub(/\./,"")sub(/,/," "); print $1"00",$2}' file
(45679900 567898)
(56783300 673434)