Nano Hash - криптовалюты, майнинг, программирование

установка числового формата по умолчанию в awk

Я хотел сделать простой разбор двух файлов с идентификаторами и некоторыми соответствующими числовыми значениями. Я не хотел, чтобы awk печатал числа в экспоненциальном представлении.

Файл выглядит так:

someid-1 860025 50.0401 4.00022
someid-2 384319 22.3614 1.78758
someid-3 52096 3.03118 0.242314
someid-4 43770 2.54674 0.203587
someid-5 33747 1.96355 0.156967
someid-6 20281 1.18004 0.0943328
someid-7 12231 0.711655 0.0568899
someid-8 10936 0.636306 0.0508665
someid-9 10224.8 0.594925 0.0475585
someid-10 10188.8 0.59283 0.047391

при использовании print вместо printf :

awk 'BEGIN{FS=OFS="\t"} NR==FNR{x[$1]=$0;next} ($1 in x){split(x[$1],k,FS); print $1,k[2],k[3],k[4],$2,$3,$4}' OSCAo.txt dme_miRNA_PIWI_OSC.txt | sort -n -r -k 7 | head

я получаю этот результат:

dme-miR-iab-4-5p      0.333333    0.000016    0.000001  0.25    0.000605606 9.36543e-07
dme-miR-9c-5p   10987.300000      0.525413    0.048798  160.2   0.388072    0.000600137
dme-miR-9c-3p   731.986000    0.035003    0.003251  2.10714 0.00510439  7.89372e-06
dme-miR-9b-5p   30322.500000      1.450020    0.134670  595.067 1.4415  0.00222922
dme-miR-9b-3p   2628.280000   0.125684    0.011673  48  0.116276    0.000179816
dme-miR-9a-3p    10.365000    0.000496    0.000046  0.25    0.000605606 9.36543e-07
dme-miR-999-5p  103.433000    0.004946    0.000459  0.0769231   0.00018634  2.88167e-07
dme-miR-999-3p  1513.790000   0.072389    0.006723  28  0.0678278   0.000104893
dme-miR-998-5p  514.000000    0.024579    0.002283  73  0.176837    0.000273471
dme-miR-998-3p  3529.000000   0.168756    0.015673  42  0.101742    0.000157339

Обратите внимание на научное обозначение в последнем столбце

Я понимаю, что printf с соответствующим модификатором формата может справиться с этой задачей, но код становится очень длинным. Я должен написать что-то вроде этого:

awk 'BEGIN{FS=OFS="\t"} NR==FNR{x[$1]=$0;next} ($1 in x){split(x[$1],k,FS); printf "%s\t%3.6f\t%3.6f\t%3.6f\t%3.6f\t%3.6f\t%3.6f\n", $1,k[2],k[3],k[4],$2,$3,$4}' file1.txt file2.txt > fileout.txt

Это становится неуклюжим, когда мне приходится анализировать fileout с другим файлом с аналогичной структурой.

Есть ли способ указать числовой вывод по умолчанию, чтобы любая строка печаталась как строка, но все числа соответствовали определенному формату.

24.04.2013

  • будет ли это работать так, как вы хотите, если вы используете %9s вместо %3.6f? 24.04.2013
  • OFMT используется, когда строки преобразуются в числа, а CONVFMT используется, когда делается наоборот. деталь. Я не уверен, как преобразовать ваш пример, чтобы использовать это, потому что мне непонятно, что вы пытаетесь сделать. 24.04.2013
  • @ Тор. спасибо .. исправил вопрос .. я хотел знать, есть ли способ назначить числовой формат вывода по умолчанию в модуле BEGIN 24.04.2013

Ответы:


1

Я думаю, что Вы неверно истолковали значение %3.6f. Первое число перед запятой — это ширина поля, а не «количество цифр до запятой». (См. print(3))

Поэтому вместо этого вы должны использовать %10.6f. Его можно легко проверить в bash

$ printf "%3.6f\n%3.6f\n%3.6f" 123.456 12.345 1.234
123.456000
12.345000
1.234000
$ printf "%10.6f\n%10.6f\n%10.6f" 123.456 12.345 1.234
123.456000
 12.345000
  1.234000

Вы можете видеть, что последнее правильно выравнивается по десятичной точке.

Как уже упоминалось sidharth c nadhan, вы можете использовать внутреннюю переменную OFMT awk (кажется awk(1)) . Пример:

$ awk 'BEGIN{print 123.456; print 12.345; print 1.234}'
123.456
12.345
1.234
$ awk -vOFMT=%10.6f 'BEGIN{print 123.456; print 12.345; print 1.234}'
123.456000
 12.345000
  1.234000

Как я вижу в вашем примере, число с максимальным количеством цифр может быть 123456.1234567, поэтому формат %15.7f покрывает все и показывает красивую таблицу.

Но, к сожалению, это не сработает, если в числе нет десятичной точки или даже если она есть, но заканчивается на .0.

$ awk -vOFMT=%15.7f 'BEGIN{print 123.456;print 123;print 123.0;print 0.0+123.0}'
    123.4560000
123
123
123

Я даже попробовал функцию strtonum() gawk, но целые числа считаются строками, отличными от OFMT. Видеть

awk -vOFMT=%15.7f -vCONVFMT=%15.7f 'BEGIN{print 123.456; print strtonum(123); print strtonum(123.0)}'

Он имеет тот же выход, что и раньше.

Так что я думаю, вам все равно придется использовать printf. Сценарий может быть немного короче и немного более настраиваемым:

awk -vf='\t'%15.7f 'NR==FNR{x[$1]=sprintf("%s"f f f,$1,$2,$3,$4);next}$1 in x{printf("%s"f f f"\n",x[$1],$2,$3,$4)}' file1.txt file2.txt

Скрипт не будет работать должным образом, если в первом файле есть повторяющиеся идентификаторы. Если этого не происходит, то два условия можно изменить, а ;next можно не использовать.

24.04.2013
  • спасибо .. но это все еще не решает проблему научной записи. например 5-e06 следует печатать как 0,0000005. 24.04.2013
  • @bharat_iyengar: Да, это так. См. echo 5e-6|awk '{printf("%14.6f",$1)}' отпечатки " 0.000005". Это ожидаемо, не так ли? 24.04.2013
  • да, это так ... но если у вас есть несколько числовых полей для печати, и вы не хотите писать %10.6f для каждого из них: возможно ли это? 24.04.2013
  • @bharat_iyengar: я также проверил обычные OFMT и CONVFMT, но это не решает проблему, заключающуюся в том, что строка, содержащая только числа, считается целым числом, а не числом с плавающей запятой, поэтому эти определенные форматы не используются (см. конверсия gawk(3)). Но это также относилось к таким числам, как 123.0. Итак, чтобы напечатать целое число как число с плавающей запятой, вы должны использовать printf. В представленном решении вам нужно указать выходной формат только один раз. Разве это не правильное решение вашей проблемы? 24.04.2013
  • @bharat_iyengar: Как я показал, вы можете установить формат для float чисел, но он не будет работать для integers (123,0 считается целым числом в awk). Поэтому, если вы смешиваете их, вам нужно использовать printf. Но вы можете уменьшить количество использования строки формата. Смотрите мои примеры. 25.04.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..