在awk中设置默认数字格式
我想用ID和一些相应的数值对两个文件进行简单的解析。我不想让awk用科学记数法打印数字 文件如下所示:在awk中设置默认数字格式,awk,formatting,Awk,Formatting,我想用ID和一些相应的数值对两个文件进行简单的解析。我不想让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 somei
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
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
使用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可以完成这项工作,但是代码变得非常冗长。我必须这样写:
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
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
时,这会变得很笨拙
是否有任何方法可以指定默认的数字输出,这样任何字符串都可以像字符串一样打印,但所有数字都遵循特定的格式。我认为您误解了
%3.6f
的含义。小数点前的第一个数字是字段宽度,而不是“小数点前的位数”。(见附件)
awk 'NR==FNR{x[$1]=$0;next} ($1 in x){split(x[$1],k,FS); printf "%s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\n", $1,k[2],k[3],k[4],$2,$3,$4}' file1.txt file2.txt > fileout.txt
因此,您应该使用%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
您可以看到后者正确地与小数点对齐
正如Sidhart c nadhan所述,您可以使用OFMT
awk
内部变量(seem)。例如:
$ 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
我甚至尝试了gawk
的strtonum()
函数,但整数被视为非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
如果第一个文件中存在重复的ID,脚本将无法正常工作。如果没有发生,则可以更改这两个条件,并且
;下一步
可以省略。我想你误解了%3.6f
的含义。小数点前的第一个数字是字段宽度,而不是“小数点前的位数”。(见附件)
因此,您应该使用%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
您可以看到后者正确地与小数点对齐
正如Sidhart c nadhan所述,您可以使用OFMT
awk
内部变量(seem)。例如:
$ 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
我甚至尝试了gawk
的strtonum()
函数,但整数被视为非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
如果第一个文件中存在重复的ID,脚本将无法正常工作。如果没有发生,则可以更改这两个条件,并且
;下一步
可以省去。如果使用%9s本身而不是%3.6f,它会按照您想要的方式工作吗?OFMT
在字符串转换为数字时使用,反之则使用CONVFMT
,请参阅我的讨论了解更多细节。我不知道如何将你的例子转换为使用这个,因为我不清楚你想做什么。@Thor。谢谢更正了这个问题。。我想知道是否有任何方法可以在BEGIN
模块中指定默认的数字输出格式如果使用%9s本身而不是%3.6f,它会按照您想要的方式工作吗?OFMT
在字符串转换为数字时使用,反之则使用CONVFMT
,请参阅我的讨论了解更多详细信息。我不知道如何将你的例子转换为使用这个,因为我不清楚你想做什么。@Thor。谢谢更正了这个问题。。我想知道是否有任何方法可以在BEGIN
moduleTanks.中指定默认的数字输出格式。。但是它仍然不能解决科学记数法的问题。例如,5-e06应打印为0。0000005@bharat_iyengar:是的。请参见echo 5e-6 | awk'{printf(“%14.6f”,$1)}
prints“0.000005”
。这是意料之中的事,不是吗?是的。。但是,如果要打印多个数字字段,并且不想为每个字段写入%10.6f
:可能吗?@bharat_iyengar:我也检查了mt和CONVFMT
的“正常”,但这并不能解决只包含数字的字符串被视为整数而不是浮点的问题,因此,不使用这些已定义的格式(请参阅)。但这也适用于像123.0
这样的数字。因此,要将整数打印为浮点,必须使用printf
。在提供的解决方案中,只需指定一次输出格式。这不是解决您问题的正确方法吗?@bharat_iyengar:正如我所展示的,您可以设置浮点
数字的格式,但它对整数
不起作用(awk将123.0视为整数)。因此,如果将它们混合使用,则需要使用printf
。但是您可以减少格式字符串的使用数量。看看我的例子,谢谢。。但是它仍然不能解决科学记数法的问题。例如,5-e06应打印为0。0000005@bharat_iyengar:是的。请参见echo 5e-6 | awk'{printf(“%14.6f”,$1)}
prints“0.000005”
。这是意料之中的事,不是吗?是的。。但是如果要打印多个数字字段,并且不想为每个字段写入%10.6f
:是否可能