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
}'
Linux AWK命令示例

特定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的函数,然后我们在脚本中使用它来打印输出。

日期:2020-07-15 11:16:53 来源:oir作者:oir