awk命令

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

1. 语法与选项

  1. 语法:awk [可选项] '模式操作 | 模式操作 | 模式操作

  2. 说明

    1. 可选项:
      1. -F '分隔符':默认分隔符是"空白键" 或 “\t键”,可以不用 -F 指定
      2. -v:用于将外部变量值传递给awk。比如:
        temp=10
        awk -v a=$temp '{print $1,$1+a}' log.txt
        
      3. -f:scriptfile 从脚本文件中读取awk命令
    2. 模式与操作
      1. 模式:模式可以是以下任意一种
        ① 正则表达式:使用通配符的扩展集
        ② 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试
        ③ 模式匹配表达式:用运算符~(匹配)和~!不匹配
        BEGIN 语句块pattern语句块END语句块
      2. 操作:操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大刮号内,主要部分是:变量或数组赋值、输出命令、内置函数、控制流语句。
  3. awk最常用的模式操作是:

    awk [可选项] 'BEGIN{ commands } pattern{ commands } END{ commands }' file_name
    

    接下来详细介绍这个。

2. awk执行过程

AWK 工作流程可分为三个部分:

  1. 读输入文件之前执行的代码段(由BEGIN关键字标识)。

  2. 读取文件时主循环逐行执行的代码段。(partter, 如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行。)

    细节:BEGIN使用printprintf输出的字符串,不会在这个模块被处理。
    在这里插入图片描述

  3. 读取数据完毕之后执行的代码段(由END关键字标识)。
    在这里插入图片描述

通常我们会将变量初始化语句放在BEGIN语句块中,将打印结果等语句放在END语句块中。通过一个例子理解:
1、先创建一个名为 marks.txt 的文件。其中包括序列号、学生名字、课程名称与所得分数。

1)    张三    语文    80
2)    李四    数学    90
3)    王五    英语    87

2、接下来,我们将使用 AWK 脚本来显示输出文件中的内容,同时输出表头信息。

awk 'BEGIN{printf "序号\t名字\t课程\t分数\n"} {print}' marks.txt

执行结果如下:

序号    名字    课程    分数
1)    张三    语文    80
2)    李四    数学    90
3)    王五    英语    87

3. 变量

3.1 内置变量

  1. 指定列:

    1. $0:选中所有列
    2. $1:选中第一列
    3. $1, $2, $3:同时选中多列
    4. $NF:选中最后一列
  2. NF : 表示字段数,在执行过程中对应于当前的字段数。 print $NF打印一行中最后一个字段

  3. NR : 表示记录数,在执行过程中对应于当前的行号

  4. FS:输入时的分隔符变量,可以是任意字符或者正则表达式。(默认是以空格\t做分隔)

    # 可以通过可选项 -F 指定分隔符
    awk -F '\t' 'print $1'
    # 也可以通过设置 FS 指定分隔符
    awk 'BEGIN{FS="\t"}{print $1}'
    

    如果两者同时指定,以FS为准。

  5. OFS:输入时的分隔符变量,可以是任意字符或者正则表达式。主要是会影响printprintf。()默认以空格为分隔

    $ awk -F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd
    41=41
    100=101
    101=102
    103=7
    105=111
    110=116
    111=117
    112=11
    
  6. RS(Record Separator) 定义了一行记录。读取文件时,默认将一行作为一条记录。 下面的例子以 student.txt 作为输入文件,记录之间用两行空行分隔,并且每条记录的每个字段用一个换行符分隔:

    cat student.txt
    Jones
    2143
    78
    84
    77
    
    Gondrol
    2321
    56
    58
    45
    
    $ cat student.txt | awk
    BEGIN {
        RS="\n\n";
        FS="\n";
    }
    {
        print $1,$2;
    }
    # 输出:
    Jones 2143
    Gondrol 2321
    RinRao 2122
    Edwin 2537
    Dayan 2415
    
  7. FILENAME: 当前输入文件的名字

3.2 引入外部变量

通过可选参数-v,其实前面以及说明过:

temp=10
awk -v a=$temp '{print $1,$1+a}' log.txt

3.3 数组

(1) 一维数组

AWK 可以使用关联数组这种数据结构,索引可以是数字字符串。AWK关联数 组也不需要提前声明其大小,因为它在运行时可以自动的增大或减小。

和java语法一样:

  1. 创建数组&添加元素&查看数组
    awk 'BEGIN {
    	sites["runoob"]="www.runoob.com";
    	sites["google"]="www.google.com";
    	print sites["runoob"] "\n" sites["google"]
    }'
    
  2. 删除数组元素
    awk 'BEGIN {
    	sites["runoob"]="www.runoob.com"; // 定义数组,并添加元素
    	delete sites["runoob"];  // 删除元素
    }'
    

(2) 多维数组

AWK 本身不支持多维数组,不过我们可以很容易地使用一维数组模拟实现多维数组。

awk 'BEGIN {
array["0,0"] = 100;
array["0,1"] = 200;
array["0,2"] = 300;
array["1,0"] = 400;
array["1,1"] = 500;
array["1,2"] = 600;
# 输出数组元素
print "array[0,0] = " array["0,0"];
print "array[0,1] = " array["0,1"];
print "array[0,2] = " array["0,2"];
print "array[1,0] = " array["1,0"];
print "array[1,1] = " array["1,1"];
print "array[1,2] = " array["1,2"];
}'

4. awk运算

  1. 算术运算:(+,-,*,/,&,!,……,++,–)所有用作算术运算符进行操作时,操作数自动转为数值,所有非数值都变为0
  2. 赋值运算:(=, +=, -=,*=,/=,%=,……=,**=)
  3. 逻辑运算符: (||, &&)
  4. 关系运算符:(<, <=, >,>=,!=, ==)
  5. 正则运算符:(~,~!)(匹配正则表达式,与不匹配正则表达式)awk 'BEGIN{a=“100testa”;if(a ~ /^100*/){print “ok”;}}'ok

5. 控制语句

5.1 分支语句

和Java代码一样,语法如下:

if (condition1) {
	action1;
	action2;
	...
}
else if (condition2) {
	action1;
	action2;
	...
}
else {
	action1;
	action2;
	...
}

细节:

  1. 和java一样,单代码块中只有一条语句时,可以省略花括号。
  2. 语句以封号结尾。

例子:

awk 'BEGIN {
    num = 11; 
    if (num % 2 == 0) printf "%d 是偶数\n", num; 
    else printf "%d 是奇数\n", num 
}'

5.2 循环语句

也是和java一样,语法如下:

  1. for循环:

    awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'
    

    细节:这里不需要定义数据类型

  2. while循环:

    awk 'BEGIN {i = 1; while (i < 6) { print i; ++i} }'
    

    细节:这里不需要定义数据类型

  3. break语句:

    awk 'BEGIN {
       sum = 0; for (i = 0; i < 20; ++i) { 
          sum += i; 
          if (sum > 50) 
          	break; 
          else 
          	print "Sum =", sum 
       } 
    }'
    
  4. Continue语句:

    awk 'BEGIN {
    	for (i = 1; i <= 20; ++i) {
    		if (i % 2 == 1) 
    			continue ; 
    		else 
    			print i
    	}
    }'
    

for循环
for(变量 in 数组)
{语句}

for(变量;条件;表达式)
{语句}
while循环
while(表达式)
{语句}
do…while循环
do
{语句} while(条件)
其他相关语句
break:退出程序循环
continue: 进入下一次循环
next:读取下一个输入行
exit:退出主输入循环,进入END,若没有END或END中有exit语句,则退出脚本。

6. 内置函数

https://www.runoob.com/w3cnote/awk-built-in-functions.html

7. 常用组合

  1. \t切分后,用#拼接,然后输出
    cat /xxxx | awk -F'\t' '{gsub(/\t/, "#"); print $0}' | more
    
  2. 切分后,依次打印所有列
    echo "A B C D E F" | awk '{for(i=1;i<=NF;i++) print $i}'
    # 输出:
    A
    B
    C
    D
    E
    F
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElegantCodingWH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值