📜  Unix/Linux 中的 AWK 命令示例

📅  最后修改于: 2022-05-13 01:57:29.681000             🧑  作者: Mango

Unix/Linux 中的 AWK 命令示例

awk 是一种用于操作数据和生成报告的脚本语言。awk 命令编程语言不需要编译,允许用户使用变量、数字函数、字符串函数和逻辑运算符。

awk 是一个实用程序,它使程序员能够以语句的形式编写微小但有效的程序,这些语句定义要在文档的每一行中搜索的文本模式以及在文档中找到匹配项时要采取的操作线。 awk 主要用于模式扫描和处理。它搜索一个或多个文件以查看它们是否包含与指定模式匹配的行,然后执行相关操作。

Awk 是开发人员名字的缩写——Aho、Weinberger 和 Kernighan。

我们可以用 AWK 做什么?

一、AWK操作:
(a) 逐行扫描文件
(b) 将每个输入行拆分为字段
(c) 将输入行/字段与模式进行比较
(d) 在匹配的行上执行操作



2. 适用于:
(a) 转换数据文件
(b) 生成格式化报告

3. 编程结构:
(a) 格式化输出行
(b) 算术和字符串运算
(c) 条件和循环

句法:

awk options 'selection _criteria {action }' input-file > output-file

选项:

-f program-file : Reads the AWK program source from the file 
                  program-file, instead of from the 
                  first command line argument.
-F fs            : Use fs for the input field separator

示例命令

例子:
将以下文本文件视为以下所有情况的输入文件。

$cat > employee.txt 

ajay manager account 45000
sunil clerk account 25000
varun manager sales 50000
amit manager account 47000
tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
satvik director purchase 80000 

1. Awk 的默认行为:默认情况下,Awk 打印指定文件中的每一行数据。



$ awk '{print}' employee.txt

输出:

ajay manager account 45000
sunil clerk account 25000
varun manager sales 50000
amit manager account 47000
tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
satvik director purchase 80000 

在上面的例子中,没有给出模式。所以这些动作适用于所有行。没有任何参数的操作打印默认打印整行,因此它打印文件的所有行而不会失败。

2. 打印与给定模式匹配的行。

$ awk '/manager/ {print}' employee.txt 

输出:

ajay manager account 45000
varun manager sales 50000
amit manager account 47000 

在上面的例子中,awk 命令打印所有与“manager”匹配的行。

3. 将一行拆分为字段:对于每条记录,即行,awk 命令默认拆分由空格字符分隔的记录,并将其存储在 $n 变量中。如果该行有 4 个单词,则将分别存储在 $1、$2、$3 和 $4 中。另外,$0 代表整条线。

$ awk '{print $1,$4}' employee.txt 

输出:



ajay 45000
sunil 25000
varun 50000
amit 47000
tarun 15000
deepak 23000
sunil 13000
satvik 80000 

在上面的例子中,$1 和 $4 分别代表 Name 和 Salary 字段。

awk 中的内置变量

Awk 的内置变量包括字段变量——$1、$2、$3 等等($0 是整行)——它们将一行文本分成单独的单词或称为字段的片段。

NR: NR 命令保持输入记录数的当前计数。请记住,记录通常是行。 awk 命令为文件中的每条记录执行一次模式/动作语句。

NF: NF 命令保留当前输入记录中字段数的计数。

FS: FS 命令包含字段分隔字符,用于分隔输入行上的字段。默认是“空白”,意思是空格和制表字符。 FS 可以重新分配给另一个字符(通常在 BEGIN 中)以更改字段分隔符。

RS: RS 命令存储当前记录分隔字符。由于默认情况下输入行是输入记录,因此默认记录分隔字符是换行符。

OFS: OFS 命令存储输出字段分隔符,用于在 awk 打印它们时分隔字段。默认为空格。每当 print 有几个参数用逗号分隔时,它会在每个参数之间打印 OFS 的值。

ORS: ORS 命令存储输出记录分隔符,用于在 awk 打印时分隔输出行。默认值是一个字符。 print 在任何要打印的内容结束时自动输出 ORS 的内容。



例子:

使用 NR 内置变量(显示行号)

$ awk '{print NR,$0}' employee.txt 

输出:

1 ajay manager account 45000
2 sunil clerk account 25000
3 varun manager sales 50000
4 amit manager account 47000
5 tarun peon sales 15000
6 deepak clerk sales 23000
7 sunil peon sales 13000
8 satvik director purchase 80000 

在上面的示例中,带有 NR 的 awk 命令打印所有行以及行号。

使用 NF 内置变量(显示最后一个字段)

$ awk '{print $1,$NF}' employee.txt 

输出:

ajay 45000
sunil 25000
varun 50000
amit 47000
tarun 15000
deepak 23000
sunil 13000
satvik 80000 

在上面的例子中,$1 代表姓名,$NF 代表薪水。我们可以使用 $NF 获取薪水,其中 $NF 代表最后一个字段。

NR 内置变量的另一种用途(Display Line From 3 to 6)

$ awk 'NR==3, NR==6 {print NR,$0}' employee.txt 

输出:

3 varun manager sales 50000
4 amit manager account 47000
5 tarun peon sales 15000
6 deepak clerk sales 23000 

更多例子

对于给定的文本文件:

$cat > geeksforgeeks.txt

A    B    C
Tarun    A12    1
Man    B6    2
Praveen    M42    3

1)打印geeksforgeeks.txt中每一行的第一项以及行号(NR),以“-”分隔:

$ awk '{print NR "- " $1 }' geeksforgeeks.txt

1 - Tarun
2 – Manav    
3 - Praveen

2) 从 geeksforgeeks.txt 返回第二行/项目:
问题应该是:-从 geeksforgeeks.txt 返回第二列/项目:

$ awk '{print $2}' geeksforgeeks.txt

A12
B6
M42

3)打印任何非空行(如果存在)



$ awk 'NF < 0' geeksforgeeks.txt

这里NF应该不小于0。并且用户还必须打印行号:

正确答案:awk 'NF == 0 {print NR}' geeksforgeeks.txt

或者
awk 'NF <= 0 {print NR}' geeksforgeeks.txt

0

4)要找到文件中存在的最长行的长度:

$ awk '{ if (length($0) > max) max = length($0) } END { print max }' geeksforgeeks.txt

13

5) 计算文件中的行数:

$ awk 'END { print NR }' geeksforgeeks.txt

3

6) 打印超过 10 个字符:

$ awk 'length($0) > 10' geeksforgeeks.txt

Tarun    A12    1
Praveen    M42    3

7) 要查找/检查任何特定列中的任何字符串:

$ awk '{ if($3 == "B6") print $0;}' geeksforgeeks.txt

8) 要打印从 1 到 n 的第一个数字的平方,比如 6:

$ awk 'BEGIN { for(i=1;i<=6;i++) print "square of", i, "is",i*i; }'

square of 1 is 1
square of 2 is 4
square of 3 is 9
square of 4 is 16
square of 5 is 25
square of 6 is 36