awk 格式化打印
awk中的printf命令允许您使用格式说明符打印格式化输出。
格式说明符的编写方式如下:
%[modifier]control-letter
可用于printf的格式说明符:
c将数字输出打印为字符串。
d打印整数值。
e打印科学号码。
f打印浮点值。
o打印八进制值。
s打印文本字符串。
使用printf来格式化我们的输出:
$ awk 'BEGIN{
x = 100 * 100
printf "The result is: %e\n", x
}'
特定AWK命令或者GNU AWK为文本处理提供了一种脚本语言。
使用awk脚本语言,我们可以进行以下操作:
- 定义变量。
- 使用字符串和算术运算符。
- 使用控制流程和循环。
- 生成格式化的报告。
其他awk变量
还有一些其他变量可以获取更多信息:
ARGC 获取传递参数的数量。
ARGV 获取命令行参数。
ENVIRON shell环境变量和相应值的数组。
FILENAME 由awk处理的文件名。
NF 正在处理的行的字段数。
NR 处理的记录总数
FNR 正在处理的记录
IGNORECASE 忽略大小写
让我们看一些示例:
$ awk 'BEGIN{print ARGC,ARGV[1]}' myfile
ENVIRON变量 可以查看shell环境变量,如下所示:
$ awk '
BEGIN{
print ENVIRON["PATH"]
}'
可以在不使用ENVIRON变量的情况下使用bash变量,如下所示:
$ echo | awk -v home=$HOME '{print "My home is " home}'
NF变量指定记录中的最后一个字段,不需要知道其位置:
$ awk 'BEGIN{FS=":"; OFS=":"} {print ,$NF}' /etc/passwd
如果这样写:$NF, NF变量可用作数据字段变量。
让我们看两个例子,来了解FNR和NR变量之间的区别:
$ awk 'BEGIN{FS=","}{print ,"FNR="FNR}' myfile myfile
在此示例中,AWK命令定义了两个输入文件。
同一个文件,但处理了两次。
输出是第一个字段值和FNR变量。
现在,换成NR变量并查看不同:
$ awk '
BEGIN {FS=","}
{print ,"FNR="FNR,"NR="NR}
END{print "Total",NR,"processed lines"}' myfile myfile
FNR变量在第二个文件时变为1,但NR变量会保持其值。
awk预处理
如果我们需要在输出结果中创建标题,
我们可以使用Begin关键字来实现此功能。
它将在处理数据之前运行:
$ awk 'BEGIN {print "Report Title"}'
示例:
$ awk 'BEGIN {print "The File Contents:"}
{print 10
15
6
33
45
}' myfile
awk结构化命令
awk 条件语句
AWK脚本语言支持if 条件语句。
testfile包含以下内容:
$ awk '{if ( > 30) print }' testfile
找出大于30的记录
$ awk '{
if ( > 30)
{
x = * 3
print x
}
}' testfile
就是这么简单。
如果要运行多个语句,则应使用括号:
$ awk '{
if ( > 30)
{
x = * 3
print x
} else
{
x = / 2
print x
}}' testfile
我们可以这样使用else语句:
$awk '{if ( > 20) print *2;else print /2 ' testfile
或者在同一行中(if语句后面使用分号)
$ cat myfile 124 127 130 112 142 135 175 158 245 118 231 147
awk while循环
我们可以使用while循环来迭代数据。
测试数据文件:
$ awk '{
sum = 0
i = 1
while (i < 5)
{
sum += $i
i++
}
average = sum / 3
print "Average:",average
}' testfile
awk while循环示例:
$ awk '{
tot = 0
i = 1
while (i < 5)
{
tot += $i
if (i == 3)
break
i++
}
average = tot / 3
print "Average is:",average
}' testfile
我们可以使用break命令提前退出循环:
$ awk '{
total = 0
for (var = 1; var < 5; var++)
{
total += $var
}
avg = total / 3
print "Average:",avg
}' testfile
awk for循环
awk脚本语言也支持for 循环:
$ echo "Hello Tom" | awk '{="Adam"; print Hello Adam
}'
在awk中执行多个命令
要运行多个命令,请使用像这样的分号分隔:
$ awk options program file
第一个命令使$2字段 等于 Adam。
第二个命令打印整行。
输出:
$ awk 'BEGIN{x=exp(5); print x}'
awk选项
awk命令语法
$ awk '{print }' myfile
Awk 可以使用的选项有:
-f fs 指定文件分隔符。
-f file指定包含awk脚本的文件。
-v var = value声明变量。
awk 内置函数
Awk提供了几种内置的函数,例如:
数学函数
我们可以在AWK脚本中使用这些数学函数:
sin(x) | cos(x) | sqrt(x) | exp(x) |log(x) | rand()
$ awk -F: '{print }' /etc/passwd
使用awk变量
使用awk,我们可以处理文本文件。
awk为找到的每个数据字段分配一些变量:
- $0 整行
- $1 第一字段
- $2 第一字段
- $n 第n字段
空白字符(空格或者tab制表符)在awk中用于字段之间的默认分隔符。
查看下面的示例,看awk是如何处理的。
$ awk 'BEGIN{x = "onitroad"; print toupper(x)}'
上面的示例将打印每行的第一个单词(字段)。
有时某些文件中的分隔符不是空格,而是其他字符。
这时我们可以使用-F选项指定它:
$ awk 'BEGIN {print "The File Contents:"}
{print BEGIN {
print "用户及其对应Home路径:"
print " UserName \t HomePath"
print "___________ \t __________"
FS=":"
}
{
print " \t "
}
END {
print "The end"
}
}
END {print "File footer"}' myfile
此命令打印在passwd文件中的第一个字段。
我们使用冒号作为分隔符。
字符串函数
有许多字符串函数,例如:
$ awk -f myscript /etc/passwd
查看手册获取根据其他函数。
Awk后处理
要在处理数据后运行脚本,请使用END关键字:
{print " home at " }
这很有用,我们可以使用它来添加一个页脚。
示例:
myscript
$ awk -F: -f testfile /etc/passwd
执行:
{
text = " home at "
print text
}
从文件中读取awk脚本
我们可以输入来自文件的AWK脚本,使用-f选项指定该文件。
假设testfile文件包含以下脚本内容:
$ awk -F: -f testfile /etc/passwd
执行脚本:
root home at /root onitroad home at /oir apache home at /var/www
脚本还可以这样写:
$ awk 'BEGIN{FS=":"; OFS="-"} {print ,,}' /etc/passwd
1235.96521 927-8.3652 36257.8157
输出:
$ awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print ,,}' testfile
awk内置变量
我们刚才看到了数据字段变量$ 1,2 $ 3用于提取数据字段,还有字段分隔符变量FS。
除此之外,还有其他的内置变量。
以下列表显示了awk中一些内置变量:
FIELDWIDTHS 指定字段宽度。
RS 指定记录分隔符。
FS 指定字段分隔符。
OFS 指定输出分隔符。
ORS 指定输出分隔符。
默认情况下,OFS变量是空格,我们可以设置OFS变量以指定所需的分隔符:
123 5.9 6521 927 -8.3 652 362 57.8 157
有时,字段间没有固定的分隔符。在这些情况下,可以使用FIELDWIDTHS变量来解决这个问题。
假设我们有这个内容:
Person Name 123 High Street (222) 466-1234 Another person 487 High Street (523) 643-8754
$ awk 'BEGIN{FS="\n"; RS=""} {print ,}' addresses
根据字段的宽度进行分割。
输出:
$ awk '
BEGIN{
test="Welcome to onitroad website"
print test
}'
如果数据在不同的行:
$ awk '{print "Welcome to awk command tutorial "}'
在上面的示例中,AWK无法正确处理字段,因为该字段由换行符而不是空格分隔。
我们需要将FS设置为换行符,RS设置为空白文本。这样空白行将当做分隔符:
$ awk '
function myfunc()
{
printf "The user %s has home path at %s\n", ,
}
BEGIN{FS=":"}
{
myfunc()
}' /etc/passwd
awk用户定义的变量
变量名称可能是任何字符,但它不能以数字开头。
我们可以将变量分配为shell脚本中的变量,像这样:
##代码##awk脚本
要定义AWK脚本,使用由单引号包围的大括号,如下所示:
##代码##要终止程序,请按Ctrl + D。
awk用户定义的函数
我们可以自己定义函数,如下所示:
##代码##我们定义了一个名为myprint的函数,然后我们在脚本中使用它来打印输出。
