awk入门(四)--awk的输出

awk可以通过print和printf来输出处理完成的内容
awk输出可以通过标准输出或重定向的方式完成
awk版本4.2.0,低版本可能有些功能有差异

输出方式:
print "elem1","elem2"...
print ("elem1","elem2"...)
(1)输出的内容是字符串时,字符串需要使用双引号包围,否则将被当做变量处理
(2)输出的各个字段中,需要使用逗号来分隔(print "elem1","elem2",...)
(3)默认情况下,输出的各个内容是使用空格分隔的,也可以设置变量OFS(Output Filed Separator)
(awk 'BEGIN{OFS="-";print "hello","world"}')
(4)也可以设置变量ORS来规定输出的记录分隔符,默认就是换行符(awk 'BEGIN{ORS="-\n";print "hello","world";print "aaa"}')
`需要注意的是,设置变量时,也需要使用双引号来包围,不能使用单引号`
字符串、数字与变量的输出
默认情况下,awk的输出的每条记录的每个字段都会被当做字符串,awk的字符类型默认就只有字符串和number这两类
(1)使用双引号包围的内容会被转换成字符串
~]$ awk 'BEGIN{print typeof("22")}'
string
~]$ awk 'BEGIN{print typeof("2a)}'  
string
(2)不使用双引号包围的数字默认为number类型,数字和字符的组合默认为字符串类型
~]$ awk 'BEGIN{print typeof(22)}'
number
(3)输出变量时,会先将变量转换成实际值,然后再进行判断
~}$ awk 'BEGIN{print typeof(NF)}'
number
~]$ awk 'BEGIN{print typeof(RS)}'
string
~]$ awk 'BEGIN{print typeof("NF")}'
string
(4)未声明的变量则会输出unassigned,在输出这些unassigned的变量时,会输出为空
~]$ awk 'BEGIN{print typeof($1)}'
unassigned
~]$ awk 'BEGIN{print typeof($haha)}'
unassigned
~]$ awk 'BEGIN{print $haha}'  ##未声明的变量且未使用双引号包围,输出为空

~]$ awk 'BEGIN{print haha}'   ##未声明的变量且未使用双引号包围,输出为空
awk对于数值的处理

awk在输出数字时,会先将数字转换为字符串再进行输出,但这个这个不影响typeof对于数字类型的判断,因为typeof是先对数字进行判断, 然后才输出其数据类型的。
对于数值,print在自动转换数值为字符串时,会采用变量OFMT(Output format)定义的格式,按照sprintf()相同的格式进行格式化,OFMT默认值为%.6g,这个表示数值的整数位和小数位加起来最多只能有6位。如果数值的整数位就超过了6位,那么就采用科学计数法来输出。如果数值没有小数的话,那么数字就会被完整地输出,不受OFMT限制,因为整数转换成字符串还是整数。

~]$ awk 'BEGIN{print 2.3984869}'
2.39849
~]$ awk 'BEGIN{print 23984869}'
23984869
~]$ awk 'BEGIN{OFMT="%.5g";print 23984869}' ##即使显式指定OMFT也对整数的输出无效,这个需要使用printf
23984869 	
~]$ awk 'BEGIN{OFMT="%e";print 2398486.9}' ##对于有小数的则遵从OFMT规则,%e表示使用科学计数法,printf则可以对整数进行操作
2.398487e+06
~]$ awk 'BEGIN{OFMT="%.4f";print 3.89995}' ##%.4f表示保留四位小数,默认使用四舍五入
3.9000
~]$ awk 'BEGIN{OFMT="%d";print 3.89898}'
~]$ awk 'BEGIN{OFMT="%.0f";print 4.232}' ##%d和%.0f的结果是相同的,不过%d是直接截取,不会四舍五入,而%.0f则会四舍五入
printf

格式化字符:

%c:将数字码转换为相应ASCII的字符
%d,%i:转换为整数,直接截取而不四舍五入
%e,%E:科学计数法来输出值
%f,%F:使用浮点数输出,比如%.0f, %2.3f等等
%g,%G:使用浮点数或者科学计数法输出
%o:使用8进制来识别数字,并且将数字转换为10进制再转换成字符串输出,printf "%o",8,就会转换为10
%s:输出字符串
%x:使用16进制来识别数字,并且将数字转换为10进制再转换成字符串输出,printf "%x",16,就会转换为10
%%:输出%号

输出修饰符:修饰符需要放在格式化字符的前面

(1)N$:N为正整数,默认情况下,printf的字段列表顺序和格式化字符串中的%号是一一对应的,使用N$可以自定义指定
printf "%2$s" "%1$s","world","hello"  ##这样就会先输出第二个字符串再输出第一个字符串,结果为hello world

可以重复指定N$,若连续输出单个字符串可以printf "%2$s" "%2$s","world","hello"这样就会输出两次hello

~]$ awk 'BEGIN{printf "%2$s" "%1$s","world\n","hello\n"}'
hello
world

~]$ awk 'BEGIN{printf "%2$s" "%2$s","world\n","hello\n"}'
hello
hello

比如一个文件有三列,那么就可以这样
~]$ awk 'BEGIN{printf "%1$s" "%2$s" "%3$s","Name\t\t","Sex\t\t","Age\t\t"}' >> student.txt

(2)字符串宽度

指定字段占用的宽度,不足宽度的使用空格填充,超出的则不处理
printf "%3s",1234  这样就会输出1234,如果printf "%5s",1234则会在左部添加一个空格(默认为右对齐)
如果想要左对齐printf "%-5s",1234这样就会在右边添加一个空格了

(3)空格与+号

对于数值,可以在数字的左侧添加正负号或者空格
printf "% d,%+d",1,2,这样1的签名就会添加一个空格,2的前面会添加一个+号
对于负数,添加空格和+号都不生效

(4)可变的数值前缀

对于%o,将添加前缀0,对于%x或%X,会添加前缀0x或0X

(5)0填充

printf "%05d","3" 会输出00003
printf "%05d",3会输出00003(下划线表示签名有四个空格)
printf "%05s","3"会输出_____3
~]$ awk 'BEGIN{printf "%-05d",2}' | wc -c  ##结果为5,左对齐,右侧填充四个空格
~]$ awk "BEGIN{printf \"%'d\n\",12122212121}" ##使用逗号来优化数字
12,122,212,121

(6).prec指定精度

%d,%i,%o,%u,%x,%X的精度值最大整数位的数量
printf "%5d",1231.1会输出1231,因为d表示输出的是整数,5表示最大整数位为5
printf "%5d",123123123会原模原样的输出,因为这个本来就是整数
%e,%E,%f,%F表示小数点后保留多少位小数
%s表示最长字符数量printf "%.5s","abcdef"会输出abcde
%g,%G表示整数位加小数位的总位数
~]$ awk 'BEGIN{printf "%.6e",2321312222}'
2.321312e+09
~]$ awk 'BEGIN{printf "%.5s","abcdeffffff"}'
abcde
~]$ awk 'BEGIN{printf "%.3g",2321312222}'
2.32e+09
sprintf

sprintf对于字符串格式化的处理和printf一样,但是sprintf不会主动输出处理后的字符串,因此可以通过变量赋值然后输出变量来完成

~]$ awk 'BEGIN{a=sprintf("%.5s","hellooo");print a}'  ##输出hello
~]$ awk 'BEGIN{a=sprintf("%.5g","12312322");print a}'
1.2312e+07
重定向输出
输出对象一定要使用双引号包围,否则会当做变量处理
print[f] something > "filename"
print[f] something >> "filename"
print[f] somthing | "shell cmd"
printf[f] something |& "shell_cmd_coprocess"
(1)> filename时,第一次将覆盖文件,第二次不会覆盖文件
~]$ cat test
aaa
bbb
ccc
ddd
~]$ head -1 a.txt 
ID  name    gender  age  email          phone
~]$ awk 'NR==1{print $1 > "test";print $2 > "test"}' a.txt ##分两次分别将a.txt第一行的$1和$2输入到文件test中
~]$ cat test
ID
name
第一次打开文件输入时会覆盖test,由于没有使用close()关闭文件,则第二次输入的时候会直接输入,不会覆盖原文件
(2)将内容输出到shell命令
~]$ awk 'NR>1{cmd="sort > hehe";print $2 | cmd}END{close(cmd)}' a.txt
##cmd执行完毕后最好使用close()关闭
~]$ awk 'BEGIN{print "seq -w 01 05" | "sh"}'
##将seq命令输出给shell来执行
(3)将内容输出到coprocess,然后使用getline获取,最后输出
~]$ awk 'NR>1{cmd="sort";print $1 |& cmd;close(cmd,"to");cmd |& getline var1;close(cmd);print var1}' a.txt
##close(cmd,"to")是必须的,因为不关闭管道的话,那么cmd就会无限等待管道的EOF符
~]$ awk 'BEGIN{cmd="sort -nr"}NR>1{print $1 |& cmd}END{close(cmd,"to");while ((cmd |& getline) > 0){print $0}close(cmd,"from")}' a.txt
stdout,stderr,stdin

awk重定向可以直接使用/dev/stdin,/dev/stdout,/dev/stderr

~]$ awk 'BEGIN{print "success" > "/dev/stdout"}'
~]$ awk 'BEGIN{print "success" > "/dev/stderr"}'
~]$ awk 'BEGIN{print "success" | "cat >&2"}'
~]$ awk 'BEGIN{getline < "/dev/stdin";print $0}' ##这个类似于复读机,你输入什么他就输出什么
~]$ exec 100<> /dev/stdin
~]$ awk 'BEGIN{while((getline var1 < /dev/fd/100) > 0){print var1}}'
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值