- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
AWK的输出,主要还是靠 print 和 printf 两个函数,而这两个函数,我们前面已经用过很多次了。
print 和 printf 主要从 C 语言 借鉴而来,而且继承了 C 语言 的输出格式。
本章剩下的内容,我们就来看看 printf 支持哪些输出格式吧。
printf fmt, expr-list
参数说明
参数 | 说明 |
---|---|
fmt |
字符串字面量,用于指定输出的格式 |
expr-list |
传递给 fmt 的参数 |
例如下面的 awk printf 函数用法
printf "%d\n", 18
%d\n 是输出格式,用于指定如何输出传递的参数,而 18 则是要输出的参数,用于按照一定的语法替换 fmt 中以 % 开始的格式化符。
%d 这种以 百分号(%) 开始的字符串又称之为 格式化符,由 百分号(%) 和其它预定义的字符构成。
AWK的 printf 函数从 C 语言 借鉴而来,那么它所支持的 转义字符 也基本从 C 语言借鉴而来。
因此,如果你熟悉 C 语言的 printf() 函数,那么对于 AWK 的转义字符也会得心应手。
AWK中的 新行(换行符) \n 表示。
因此,如果你想要 Hello World 中的每一个单词一行
Hello
World
那么你只需要将 Hello World 中的 空格( ' ' ) 换成 \n 即可
[www.ddkk.com]$ awk 'BEGIN { printf "Hello\nWorld\n" }'
运行上面的 awk 命令,输出结果如下
Hello
World
后面那个 \n 是为了保证 终端( shell ) 的提示符在新的一行。
如果你想要两个或更多个字符串/字段之间有一定的间隔,一种方法是添加相当数量的 空格,比如我们想要 Hello 和 World 两个单词之间有四个空格,则可以直接使用四个空格分开
Hello World
另一种更简单的方法,就是使用 水平分隔符(制表符)\t 。
Hello\tWorld
一般情况下,一个 \t 的间隙相当于 2 个或 4 个空格,这取决于配置
我们来看一个范例
[www.ddkk.com]$ awk 'BEGIN { printf "编号\t姓名\t部门\t年龄\n";printf "编号 姓名 部门 年龄\n";}'
运行上面的 awk 命令,输出结果如下
编号 姓名 部门 年龄
编号 姓名 部门 年龄
从上面的输出可以看出,在我这台电脑上,一个 \t 等于 4 个空格。
竖直(垂直)分隔符 \v 看起来有点和 水平分隔符(制表符)\t 类似,但是,前者的功能并不是在竖直方向拉出一定的空间,而是在 新行中空出上一行所占用的空间
简单的来说,就是制作一个 楼梯 效果,比如 "编号\v姓名\v部门\v年龄\n" 的作用,其实是
编号
姓名
部门
年龄
[www.ddkk.com]$ awk 'BEGIN { printf "编号\v姓名\v部门\v年龄\n"}'
运行上面的 awk 命令,输出结果如下
编号
姓名
部门
年龄
退格符 \b 的作用,就是在之前的字符串基础上,往回退一个 字符。从某些方面说,就是删除一个前面的字符。
比如Hello\bWorld 输出的效果就是 HellWorld,也就是 \b 之前的那个 o 被删除了。
为了更逼真的演示 \b 的作用,请看下面这个范例
[www.ddkk.com]$ awk 'BEGIN { printf "Field 1Field 2Field 3Field 4\n" }'
[www.ddkk.com]$ awk 'BEGIN { printf "Field 1\bField 2\bField 3\bField 4\n" }'
运行上面的 awk 命令,输出结果如下
Field 1Field 2Field 3Field 4
Field Field Field Field 4
从输出结果中可以看出,每一个 \b 都会用于删除前一个字符和 \b 本身
在很多地方,或许你也经常听到 回车换行,也就是 \r\n,虽然 回车\r 和 换行(\n) 的效果看起来类似,但它们实实在在的有点区别的。
1、 换行符(\n)是在新行继续输出;
2、 **回车符(\r)**则是删除当前行的所有已经输出,然后回到当前行的开始重新输出,从某些方面说,就是从在当前从头开始输出;
3、 回车换行(\r\n)的意思就是回到当前行的开始并且在新行输出,从某些方面说,其实就是换行;
如果你比理解,请反复理解下面这个范例
[www.ddkk.com]$ awk 'BEGIN { printf "Field 1\nField 22\nField 333\nField 4444\n\n" }'
[www.ddkk.com]$ awk 'BEGIN { printf "Field 1\rField 22\rField 333\rField 4444\n\n" }'
[www.ddkk.com]$ awk 'BEGIN { printf "Field 1\r\nField 22\r\nField 333\r\nField 4444\n" }'
运行上面的 awk 命令,输出结果如下
Field 1
Field 22
Field 333
Field 4444
Field 4444
Field 1
Field 22
Field 333
Field 4444
从结果中可以看出,\r\n 和 \n 的作用类似,而 \r 则是实打实的从当前行开始输出
换页符 (\f) 顾名思义,就是 走纸换页,一般在 打印机打印 时才会生效,用于从一个 新页 开始输出。
如果不是在 打印机,那么输出效果和 竖直分割符(\v) 的效果类似
[www.ddkk.com]$ awk 'BEGIN { printf "Sr No\fName\fSub\fMarks\n" }'
[www.ddkk.com]$ awk 'BEGIN { printf "Sr No\vName\vSub\fMarks\n" }'
运行上面的 awk 命令,输出结果如下
Sr No
Name
Sub
Marks
Sr No
Name
Sub
Marks
AWK的 printf 函数从 C 语言 借鉴而来,那么它所支持的 格式化符 也基本从 C 语言借鉴而来。
因此,如果你熟悉 C 语言的 printf() 函数,那么对于 AWK 的格式化符也会得心应手。
如果你想要将一个数字输出为 单个字符,可以使用 %c 格式化符。
需要注意的是
1、 如果传递的是数字,这个数字必须是ASCII所支持的,也就是说小于128;
2、 如果传递的是字符串,那么只有第一个字符会被输出,其它的则直接省略;
[www.ddkk.com]$ awk 'BEGIN { printf "ASCII value 65 = character %c\n", 65 }'
[www.ddkk.com]$ awk 'BEGIN { printf "ASCII value 156 = character %c\n", 156 }'
[www.ddkk.com]$ awk 'BEGIN { printf "ASCII value ddkk = character %c\n", "ddkk" }'
运行上面的 awk 命令,输出结果如下
ASCII value 65 = character A
ASCII value 156 = character ?
ASCII value ddkk = character t
从输出结果中可以看出,如果传递的数字不能转换为 ASCII 字符,则直接输出一个 问号(?)
%d 和 %i 格式化符的作用一样,把传递的参数转换为 整数 然后输出。
需要注意的是:
1、 如果传递的是浮点数(小数),那么只会输出整数部分,小数部分直接忽略;
2、 如果传递的是非整数,则直接输出0;
3、 如果传递的是字符串整数,则会转换为整数然后输出;
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %d\n", 80 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %d\n", 80.66 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %d\n", "www.ddkk.com" }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %d\n", "80.66" }'
运行上面的 awk 命令,输出结果如下
价格 = 80
价格 = 80
价格 = 0
价格 = 80
%e 和 %E 的作用一样,把传递的参数先用 科学计数法 表示然后输出。它们的差别在于 %E 会把科学计数法表示中的所有字母都大写。
需要注意的是:
不管传递的是什么,都会先转换成科学计数法。如果传递的是字符串,首先会转换成 0 然后再转换为科学计数法
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %e\n", 80 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %e\n", 80.6699999 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %e\n", "www.ddkk.com" }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %e\n", "80.66" }'
运行上面的 awk 命令,输出结果如下
价格 = 8.000000e+01
价格 = 8.067000e+01
价格 = 0.000000e+00
价格 = 8.066000e+01
%E 会把科学计数法中的所有字母都大写。
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %E\n", 80 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %E\n", 80.6699999 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %E\n", "www.ddkk.com" }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %E\n", "80.66" }'
运行上面的 awk 命令,输出结果如下
价格 = 8.000000E+01
价格 = 8.067000E+01
价格 = 0.000000E+00
价格 = 8.066000E+01
浮点数格式化符 %f 会把传递的参数先转换为 浮点数(小数),然后输出。
需要注意的是:
1、 不管传递的是什么,都会先转换成浮点数如果传递的是字符串,首先会转换成0然后再转换为浮点数;
2、 转换的时候,如果小数位数太多(默认多余6位)则会触发四舍五入;
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %f\n", 80 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %f\n", 80.6699999 }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %f\n", "www.ddkk.com" }'
[www.ddkk.com]$ awk 'BEGIN { printf "价格 = %f\n", "80.66" }'
运行上面的 awk 命令,输出结果如下
价格 = 80.000000
价格 = 80.670000
价格 = 0.000000
价格 = 80.660000
%g 和 %G 的作用是一样的,会根据传递的参数选择 %e 或 %f 格式化符,具体选哪个,取决于转后后的结果谁更短(位数更少)。
而%G 和 %g 的区别,就是前者会把转换后的参数中的所有字母都大写。
1、 当给定的数字去掉首尾的空格后,整数部分总位数小于等于6时,使用的是%f和%F模式,且总共只保留6位数字,还会发生四舍五入;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%g |
浮点数格式输出 | printf "%g",000123.456789213 |
123.457 |
%G |
浮点数格式输出且大写 E | printf "%G",000123.456789213 |
123.456789 |
1、 当给定的数字去掉首尾的空格后,整数部分总位数大于6时,采用的是%e和%E模式,且会去掉首尾的空格,并保留6位有效小数;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%g |
科学计数法输出 | printf "%g",0005678123.456789213 |
5.67812e+06 |
%G |
科学计数法输出且大写 E | printf "%G",0005678123.456789213 |
123.456789 |
%o 用于输出一个 无符号八进制数字,准确的说是将数据先转换为无符号八进制数据然后输出
[www.ddkk.com]$ awk 'BEGIN { printf "Octal representation of decimal number 10 = %o\n", 10}'
运行以上 awk 命令,输出结果如下
Octal representation of decimal number 10 = 12
格式化符 %u 用于输出一个 无符号十进制数字,准确的说是将数据先转换为无符号十进制数据然后输出
[www.ddkk.com]$ awk 'BEGIN { printf "无符号 10 = %u\n", 10 }'
运行以上 awk 命令,输出结果如下
无符号 10 = 10
而对于小于 0 的数据,则会先转换为无符号十进制数字再输出,转换方式为先抛弃小数,然后求补码。s
[www.ddkk.com]$ awk 'BEGIN { printf "无符号 -11.332 = %u\n", -11.332 }'
运行以上 awk 命令,输出结果如下
无符号 -11.332 = 18446744073709551605
格式化符 %s 用于输出一个字符串。准确的说是将数据先转换为字符串,然后输出
[www.ddkk.com]$ awk 'BEGIN { printf "年龄 = %s\n", 28.1119 }'
运行以上 awk 命令,输出结果如下
年龄 = 28.1119
当然了,%s 还可以原样输出传递的字符串,例如
[www.ddkk.com]$ awk 'BEGIN { printf "网站 = %s\n", "/"}'
运行以上 awk 命令,输出结果如下
网站 = /
格式化符 %x 和 %X 可以用来将一个 大于 0 的十进制 格式化为 十六进制
而%X 和 %x 的区别,就是 %X 格式化生成的十六进制是大写字母,而 %x 则是小写字母
[www.ddkk.com]$ awk 'BEGIN { printf "15 转换为十六进制为: = %x\n", 15}'
运行以上 awk 命令,输出结果如下
15 转换为十六进制为: = f
如果我们把 %x 改成 %X 则会输出大写的十六进制
[www.ddkk.com]$ awk 'BEGIN { printf "15 转换为十六进制为: = %X\n", 15}'
运行以上 awk 命令,输出结果如下
15 转换为十六进制为: = F
已经学习了这么多的格式化符,我们知道,任何格式化符都是以 百分号(%) 开始的
那么,如果我们要输出 % 又要怎么做呢?
答案就是: 和 C 语言 一样,使用 两个百分号(%%) 来输出一个 %
[www.ddkk.com]$ awk 'BEGIN { printf "百分比 = %d%%\n", 80.66 }'
运行上面的 awk 命令,输出结果如下
百分比 = 80%
百分号(%) 还有一些其它非常有用的格式化组合,下面我们就来讲讲几个比较常见的
AWK使用 printf 输出时,默认是参数多长就输出多长,不会浪分一丁点空间。
但如果我们想要位某个参数指定固定的长度,则可以在 百分号(%) 后面,格式化字符之前添加指定的 长度。
例如,对于 %d 如果我们要指定占用宽度为 10 ,则可以使用格式化符 %10d。
默认情况下,当输出是 右对齐的,且左边默认填充 空格(' ')。
[www.ddkk.com]$ awk 'BEGIN {
num1 = 10; num2 = 20; printf "Num1 = %10d\nNum2 = %10d\n", num1, num2
}'
运行上面的 awk 命令,输出结果如下
Num1 = 10
Num2 = 20
在我们指定了宽度的前提下,AWK 有条默认的规则: 当输出的数字不足以填满宽度时,默认是右对齐的。例如下面的范例
[www.ddkk.com]$ awk 'BEGIN { num1 = 10;num2 = 12356; printf "Num1 = %7d\nNum2 = %7d\n", num1,num2 }' | cat -vte
输出结果如下
Num1 = 10$
Num2 = 12356$
上面的范例,有两个地方值得注意:
1、 输出默认时左对齐的,因此Num1=和Num2=垂直对齐且左对齐;
2、 当指定了宽度,默认时右对齐的10和123456就时右对齐;
如果我们想要输出的数字不足以填满宽度时仍然左对齐,则需要在百分号后类型之前面添加 负号(-)。
对于上面的范例,就是将 %7d 改成 %-7d
[www.ddkk.com]$ awk 'BEGIN { num1 = 10;num2 = 12356; printf "Num1 = %-7d\nNum2 = %-7d\n", num1,num2 }' | cat -vte
运行上面的范例,输出结果如下
Num1 = 10 $
Num2 = 12356 $
不知道你有没有留意上一条的数组结果。哈哈,去翻翻~~~~
在我们指定了宽度的前提下,AWK 还有另一条默认的规则: 当输出的数字不足以填满宽度时,默认右对齐的,且使用空格补足剩余部分。
例如下面的范例
[www.ddkk.com]$ awk 'BEGIN { num1 = 10;num2 = 12356; printf "Num1 = %7d\nNum2 = %7d\n", num1,num2 }' | cat -vte
输出结果如下
Num1 = 10$
Num2 = 12356$
这时候,如果要将默认的 空格填充 改成 0 ,比如 0 ,则需要在 百分号(%) 后面,宽度数字之前 添加 0 ,例如 %7d 改成 %07d
注意: 只能是 0 ,如果是其它字符,默认是没有任何效果的。
[www.ddkk.com]$ awk 'BEGIN {
num1 = -10; num2 = 20; printf "Num1 = %07d\nNum2 = %07d\n", num1, num2
}'
运行上面的 awk 命令,输出结果如下
Num1 = -000010
Num2 = 0000020
AWK支持输出时在数字前面添加 正负号(+-),也就是说,把 10.00 改成 +10.00,把 -10.00 改成 -10.00
哈,其实负数没啥好添加前缀的,因为人家本来就有一个 负号
要在数字前面添加正负号,只需要在 百分号(%) 后类型之前添加一个 **正号(+)**即可,比如 %d 改成 %+d,比如 %f 改成 %+f
[www.ddkk.com]$ awk 'BEGIN {
num1 = -10; num2 = 20; printf "Num1 = %+d\nNum2 = %+d\n", num1, num2
}'
输出结果为
Num1 = -10
Num2 = +20
比如
[www.ddkk.com]$ awk 'BEGIN {
num1 = -10.234; num2 = 20.456; printf "Num1 = %+f\nNum2 = %+f\n", num1, num2
}'
输出结果为
Num1 = -10.234000
Num2 = +20.456000
AWK的输出还支持对数字进行格式化,比如八进制、十六进制、小数点、千分位等。具体的规则如下
1、 如果给定的值不为0,则支持八进制输出和十六进制输出;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%o |
八进制格式 | printf("%o",10) | 12 |
%#o |
八进制且附加前缀 0 |
printf("%#o",10) | 012 |
%x |
十六进制格式 | printf("%x",10) | a |
%X | 大写十六进制格式 | printf("%X",10) | A |
%#x |
十六进制格式附加前缀 0x |
printf("%#x",10) | 0xa |
%#X|大写十六进制格式附加前缀 0X |
printf("%#X",10) | 0XA |
如果给定的值为 0 则会直接输出 0 而无视各种格式符
1、 对于任意数字,都是支持以下科学计数法输出;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%e |
科学计数法输出 | printf "%e",123.456789213 |
1.234568e+02 |
%E |
科学计数法输出且大写 E | printf "%E",123.456789213 |
1.234568E+02 |
%e 和 %E 并会移除前置的 0,比如下面这个范例
awk 'BEGIN { printf "%e\n", 000001231.456789213}'
输出结果为
1.231457e+03
1、 对于任意数字,都支持以下浮点数格式化符;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%e |
科学计数法输出 | printf "%f",123.456789213 |
123.456789 |
%E |
科学计数法输出且大写 E | printf "%F",123.456789213 |
123.456789 |
注意: Mac OS 自带的 awk 不支持 %F
%f 和 %F 并会移除前置的 0,比如下面这个范例
awk 'BEGIN { printf "%f\n", 000001231.456789213}'
输出结果为
1231.456789
1、 对于任意数字,还支持以下浮点数格式化符;
%g 和 %G 是 %e、%E、%f、%F 的升级版。
1、 当给定的数字去掉首尾的空格后,整数部分总位数小于等于6时,使用的是%f和%F模式,且总共只保留6位数字,还会发生四舍五入;
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%g |
浮点数格式输出 | printf "%g",000123.456789213 |
123.457 |
%G |
浮点数格式输出且大写 E | printf "%G",000123.456789213 |
123.456789 |
格式化符 | 说明 | 范例 | 范例结果 |
---|---|---|---|
%g |
科学计数法输出 | printf "%g",0005678123.456789213 |
5.67812e+06 |
%G |
科学计数法输出且大写 E | printf "%G",0005678123.456789213 |
123.456789 |
我正在使用 OUTFILE 命令,但由于权限问题和安全风险,我想将 shell 的输出转储到文件中,但出现了一些错误。我试过的 #This is a simple shell to connect t
我刚刚开始学习 Java,我想克服在尝试为这个“问题”创建 Java 程序时出现的障碍。这是我必须创建一个程序来解决的问题: Tandy 喜欢分发糖果,但只有 n 颗糖果。对于她给第 i 个糖果的人,
你好,我想知道我是否可以得到一些帮助来解决我在 C++ 中打印出 vector 内容的问题 我试图以特定顺序在一个或两个函数调用中输出一个类的所有变量。但是我在遍历 vector 时收到一个奇怪的错误
我正在将 intellij (2019.1.1) 用于 java gradle (5.4.1) 项目,并使用 lombok (1.18.6) 来自动生成代码。 Intellij 将生成的源放在 out
编辑:在与 guest271314 交流后,我意识到问题的措辞(在我的问题正文中)可能具有误导性。我保留了旧版本并更好地改写了新版本 背景: 从远程服务器获取 JSON 时,响应 header 包含一
我的问题可能有点令人困惑。我遇到的问题是我正在使用来自 Java 的 StoredProcedureCall 调用过程,例如: StoredProcedureCall call = new Store
在我使用的一些IDL中,我注意到在方法中标记返回值有2个约定-[in, out]和[out, retval]。 当存在多个返回值时,似乎使用了[in, out],例如: HRESULT MyMetho
当我查看 gar -h 的帮助输出时,它告诉我: [...] gar: supported targets: elf64-x86-64 elf32-i386 a.out-i386-linux [...
我想循环遍历一个列表,并以 HTML 格式打印其中的一部分,以代码格式打印其中的一部分。所以更准确地说:我想产生与这相同的输出 1 is a great number 2 is a great
我有下面的tekton管道,并尝试在Google Cloud上运行。集群角色绑定。集群角色。该服务帐户具有以下权限。。例外。不确定需要为服务帐户设置什么权限。
当尝试从 make 过滤非常长的输出以获取特定警告或错误消息时,第一个想法是这样的: $ make | grep -i 'warning: someone set up us the bomb' 然而
我正在创建一个抽象工具类,该类对另一组外部类(不受我控制)进行操作。外部类在某些接口(interface)点概念上相似,但访问它们相似属性的语法不同。它们还具有不同的语法来应用工具操作的结果。我创建了
这个问题已经有答案了: What do numbers starting with 0 mean in python? (9 个回答) 已关闭 7 年前。 在我的代码中使用按位与运算符 (&) 时,我
我写了这段代码来解析输入文件中的行输入格式:电影 ID 可以有多个条目,所以我们应该计算平均值输出:**没有重复(这是问题所在) import re f = open("ratings2.txt",
我需要处理超过 1000 万个光谱数据集。数据结构如下:大约有 1000 个 .fits(.fits 是某种数据存储格式)文件,每个文件包含大约 600-1000 个光谱,其中每个光谱中有大约 450
我编写了一个简单的 C 程序,它读取一个文件并生成一个包含每个单词及其出现频率的表格。 该程序有效,我已经能够在 Linux 上运行的终端中获得显示的输出,但是,我不确定如何获得生成的显示以生成包含词
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
1.普通的输出: print(str)#str是任意一个字符串,数字··· 2.格式化输出: ?
我无法让 logstash 正常工作。 Basic logstash Example作品。但后来我与 Advanced Pipeline Example 作斗争.也许这也可能是 Elasticsear
这是我想要做的: 我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持 250 毫秒,然后通过扬声器输出。 我已经使用 Java Sound API 做到了这一点。问题是它有点慢。从发出声音到
我是一名优秀的程序员,十分优秀!