awk命令

这篇具有很好参考价值的文章主要介绍了awk命令。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

​awk是一个强大的文本处理工具。
awk把文件逐行的读入,一行叫一条记录,以空格为分隔符将每行切片,切开的部分叫域或者列或者字段,然后处理各个字段。

awk有3个不同版本:awk、nawk、gawk。
未作特别说明,一般指gawk,gawk是AWK的GNU版本。

awk其名称源自它的创始人Alfred Aho 、Peter Weinberger和Brian Kernighan姓氏的首个字母。

一、调用awk的方法

1.命令行方式

awk [options] 'commands' input-file(s)

2.脚本方式
将所有的awk命令写入一个文件,并使其可执行,然后将awk命令解释器作为脚本的首行,通过键入脚本名称来调用。

相当于shell脚本首行的#!/bin/sh换成#!/bin/awk

二、命令行方式用法

(一)语法格式

用法:awk [选项] -f 脚本文件 [--] 文件...
用法:awk [选项] [--] '程序' 文件...

(二)选项

-f 脚本文件, --file=脚本文件
-F fs, --field-separator=fs
-v var=val, --assign=var=val
-b, --characters-as-bytes
-c, --traditional
-C, --copyright
-d[文件], --dump-variables[=文件]
-D[文件], --debug[=文件]
-e '程序文本', --source='程序文本'
-E 文件, --exec=文件
-g, --gen-pot
-h, --help
-i 包含文件, --include=包含文件
-I, --trace
-l 库, --load=库
-L[fatal|invalid|no-ext], --lint[=fatal|invalid|no-ext]
-M, --bignum
-N, --use-lc-numeric
-n, --non-decimal-data
-o[文件], --pretty-print[=文件]
-O, --optimize
-p[文件], --profile[=文件]
-P, --posix
-r, --re-interval
-s, --no-optimize
-S, --sandbox
-t, --lint-old
-V, --version

(三)参数
1.程序
也叫脚本命令
格式为:

'模式{操作}'

它由两部分组成,分别为模式和操作。模式也可以叫做条件或者地址。

整个脚本命令是用单引号’'括起。为了防止shell解析特殊字符。

如果是执行多条脚本命令,格式为:

'模式1{命令1};模式2{命令2}...'

(1)模式
用来指定要处理的行。
模式可以是以下任意一个:

/正则表达式/:使用ERE。
关系表达式:使用运算符操作,可以是字符串或数字的比较测试。
包含表达式:使用运算符~(包含)和!~(不包含)。
BEGIN:如果模式是BEGIN,说明后面的操作只在程序开始时执行一次。
END:如果模式是END,说明后面的操作只在程序结束时执行一次。
模式1, 模式2:从匹配模式1的行到匹配模式2的行(包含该行)。
省略:表示处理所有行。
条件类型 条 件 说 明
awk保留字 BEGIN 在 awk 程序一开始,尚未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次
awk保留字 END 在 awk 程序处理完所有数据,即将结束时执行。END 后的动作只在程序结束时执行一次
关系运算符 > 大于
< 小于
>= 大于等于
<= 小于等于
== 等于。用于判断两个值是否相等
!= 不等于
A~B 判断字符串 A 中是否包含能匹配 B 表达式的子字符串
A!~B 判断字符串 A 中是否不包含能匹配 B 表达式的子字符串
正则表达式 /正则/ 匹配正则表达式的行

例如:

x>10:判断变量 x 是否大于10;
x == y:判断变量 x 是否等于变量 y;
A~B:判断字符串 A 中是否包含能匹配 B 表达式的子字符串;
A!~B:判断字符串 A 中是否不包含能匹配 B 表达式的子字符串;

(2)操作
操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,大括号不是必须的,但它们用于根据特定的模式对一系列指令分组,主要部分是:
变量或数组赋值
输入输出
内置函数
控制流语句

2.一个或多个文件

(四)内置变量

变量 描述
$n 当前记录的第n个字段,字段间由FS分隔,n从1开始
$0 完整的输入记录
ARGC 命令行参数的数目
ARGIND 命令行中当前文件的位置(从0开始算)
ARGV 包含命令行参数的数组
CONVFMT 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表(用空格键分隔)
FILENAME 当前文件名
FNR 各文件分别计数的行号
FS 字段分隔符(默认是任何空格)
IGNORECASE 如果为真,则进行忽略大小写的匹配
NF 一条记录的字段的数目
NR 已经读出的记录数,就是行号,从1开始
OFMT 数字的输出格式(默认值是%.6g)
OFS 输出字段分隔符,默认值与输入字段分隔符一致。
ORS 输出记录分隔符(默认值是一个换行符)
RLENGTH 由match函数所匹配的字符串的长度
RS 记录分隔符(默认是一个换行符)
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符(默认值是/034)

(五)示例用法
1.使用内置函数
最常用的内置函数就是输出函数。awk中同时提供了print和printf两种打印输出的函数。

(1)print
是默认命令。
print函数的参数可以是变量、数值、字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。

print函数的输出会把各参数用空格分开。print函数默认会在每行后面加上ORS。

如,

'{print key, "=" value}'

(2)printf
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。需要特别注意的是使用printf时默认是不会换行的,需要手动加\n。

printf 语句的格式如下:

printf(format, value1, value2, ..., valuen)

其中format是格式字符串,包含要原样打印的文本和规格(specification)。

一个规格是一个%符后面跟着一些字符,用来控制一个 value的格式。
第一个规格说明如何打印value1,第二个说明如何打印value2,依次类推。因此,有多少value要打印,在format中就要有多少个规格。

规格 说明
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x 无符号以十六进制表示的整数
%o 无符号以八进制表示的整数
%g 自动选择合适的表示法

如,

'{ printf("total pay for %s is $%.2f\n", $1, $2 * $3) }'
输出样例:
total pay for Beth is $0.00
total pay for Dan is $0.00
total pay for Kathy is $40.00
total pay for Mark is $100.00
total pay for Mary is $121.00
total pay for Susie is $76.50

第一个规格是%s,说明以字符串的方式打印第一个值 $1。
第二个是%.2f,说明以数字的方式打印第二个值$2*$3,并保留小数点后面两位。
规格字符串中其他东西,包括美元符号,原样打印。
字符串尾部的\n代表开始新的一行,使得后续输出将从下一行开始。

'{ printf("%-8s $%6.2f\n", $1, $2 * $3) }'
Beth     $  0.00
Dan      $  0.00
Kathy    $ 40.00
Mark     $100.00
Mary     $121.00
Susie    $ 76.50

第一个规格%-8s将一个姓名以字符串形式在8个字符宽度的字段中左对齐输出。
第二个规格%6.2f将薪酬以数字的形式,保留小数点后两位,在6个字符宽度的字段中输出。

(3)length函数

length([string])返回字符串的长度。比如:length("abc")返回3

length()返回$0的长度。

 从文件中找出长度大于 80 的行:

awk 'length()>80' log.txt

2.使用外部命令
(1)使用system函数执行外部命令
①语法格式

awk '{system("command")}' file

system的返回值是command执行的返回值
command必须使用双引号引起来。

②示例

awk 'BEGIN{system("ls")}' file.txt

(2)使用管道
awk中的管道概念和shell的管道类似,都是使用"|"符号。如果在awk程序中打开了管道,必须先关闭该管道才能打开另一个管道。也就是说一次只能打开一个管道。管道一旦打开,就会保持打开状态直至awk退出。

又分为两种:
一种是配合getline
一种是配合print

①配合getline
1)格式

awk '{"command" | getline [var]}' file

var是可选参数,用于存储命令执行后的标准输出,默认情况下结果输出到$0
command必须用双引号引起来。

执行的结果缓存于pipe中,再传送给awk处理,如果有多行数据,awk的getline命令可能调用多次。

2)示例

awk '{"curl www.baidu.com" | getline result; print(result);}' file.txt

$awk 'BEGIN{ while(("ls" | getline d) > 0) print d}' file.txt

②配合print或printf
1)格式

awk '{print ... | "command"}' file

command必须用双引号引用起来。
output是先缓存在pipe中,等输出完毕后再调用shell命令处理,shell命令只处理一次,而且处理的时机是“awk程序结束时,或者管道关闭时(需要显式的关闭管道)”

2)示例

$ awk 'BEGIN{print "foobar" | "echo eew"}' file.txt 
eew

$ awk 'BEGIN{count=0} /west/{count++} {printf("%s %stt%-15sn", $3,$4,$1) | "sort +1"} END{close("sort +1"); printf("The number of sales pers in the western"); print "region is " count "."}' file.txt

printf函数用于将输出格式化并发送给管道。所有输出集齐后一同发送给sort命令。
必须用与打开时完全相同的命令来关闭管道(sort +1),否则END块中的语句将与前面的输出一起被排序。
此处的sort命令只执行一次。

awk调用外部命令都是新开一个shell,所以要注意当前shell变量与新开shell变量问题

root@ubuntu:~# abc=12345567890
root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'
root@ubuntu:~#
root@ubuntu:~# export abc=12345567890
root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'
12345567890
root@ubuntu:~#
root@ubuntu:~# abc=1234567890
root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'
root@ubuntu:~#
root@ubuntu:~# export abc=1234567890
root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'
1234567890
root@ubuntu:~#

3.使用内置变量
(1)变量NF
表示当前行有多少个字段,字段从1开始编号。

$NF就代表最后一个字段。

$ echo 'this is a test' | awk '{print $NF}'
test

$(NF-1)代表倒数第二个字段。

$ awk -F ':' '{print $1, $(NF-1)}' demo.txt
root /root
daemon /usr/sbin
bin /bin
sys /dev
sync /bin

(2)删除列
比如,删除第2列,让它等于空

awk '{$2 = ""; print $0}' file
awk '{$2 = null; print $0}' file

但是这种写法会多出一个空格,如下例:

[root@centos79 test3]# cat a.txt
3 5 6 2
s g 3 5
c f h e
[root@centos79 test3]# awk '{$2 = ""; print $0}' a.txt
3  6 2
s  3 5
c  h e

删除第二列,不留空格的写法如下

awk '{$2 = "\b"; print $0}' file

如下例:

[root@centos79 test3]# cat a.txt
3 5 6 2
s g 3 5
c f h e
[root@centos79 test3]# awk '{$2 = "\b"; print $0}' a.txt
3 6 2
s 3 5
c h e

(3)统计/etc/passwd文件名,每行的行号,每行的列数

#awk -F':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7
filename:/etc/passwd,linenumber:2,columns:7
filename:/etc/passwd,linenumber:3,columns:7
filename:/etc/passwd,linenumber:4,columns:7

(4)使用自定义变量

awk中自定义变量不需要声明,默认初始值是0,所以不用初始化,可以直接使用。

例子:计算文件大小

$ ls -l *.txt | awk '{sum+=$5} END {print sum}'
666581

4.直接使用shell变量。
(1)是“双引号+单引号+shell变量+单引号+双引号”的格式

awk '{print "'$shellvar'"}' filename
$ foo=bar
$ awk 'BEGIN{print "'$foo'"}' file.txt
bar

(2)是“双引号+单引号+双引号+shell变量+双引号+单引号+双引号”的格式

awk '{print "'"$shellvar"'"}' filename

如果变量的值中包含空格,为了shell不把空格作为分隔符,则应使用这种方法

(3)export变量,然后在awk中使用ENVIRON[“var”]形式获取环境变量的值

awk '{print ENVIRON["var"]}' filename
$ export foo=bar
$ awk 'BEGIN{print  ENVIRON["foo"]}' file.txt
bar

(4)使用-v选项
定义变量时,让其值等于shell变量的值
示例:

foo=bar
awk -v awkfoo=$foo '{print awkfoo}' file.txt

实例:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

5.-F选项
默认情况下,awk会使用空格分割一行数据,但是可以使用-F选项指定分隔符。-F后面的分隔符可以用双引号,也可以用单引号,也可以不用引号。

Num,Name,Company,Product
1,Jobs,Apple,iPhone
2,Jack,Alibaba,taobao
3,Pony,Tencent,wechat

awk -F"," '{print $2"\t"$3}' form.txt
Name    Company
Jobs    Apple
Jack    Alibaba
Pony    Tencent

这里的选项 -F “,” 就表示以每行数据中的逗号为分隔符,来切分数据。

实例:

#使用","分割
 $  awk -F, '{print $1,$2}' log.txt
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 
 # 或者使用内建变量
 $ awk 'BEGIN{FS=","} {print $1,$2}' log.txt
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 
 # 使用多个分隔符
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 2 this test
 3 Are awk
 This's a
 10 There apple

6.-f选项从文件中读取程序
awk 允许将脚本命令存储到文件中,然后再在命令行中引用,比如:
假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的 awk 脚本如下:

$ cat cal.awk
#!/bin/awk
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR​
}
我们来看一下执行结果:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

7.BEGIN END模式

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

第一步:执行BEGIN{ commands }语句块中的语句;
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{ commands }语句块。

BEGIN语句块在awk开始从输入流中读取行之前执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。

END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

示例

echo -e "A line 1\nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }'
Start
A line 1
A line 2
End

8.条件表达式模式
(1)下面用一个综合的例子来说明awk的条件判断和数值计算,有这样一组数据保存为pay.txt:

Name    1st   2nd   3rd
VBird   23000   24000  25000
DMTsai  21000   20000  23000
Bird2   43000   42000  41000

现在想加一列"Total",计算每一行的数值总和。

用awk可以完成这个需求:

awk 'NR==1 {printf "%10s %10s %10s %10s %10s \n",$1,$2,$3,$4,"Total"};NR>1 {printf "%10s %10s %10s %10s %10s \n",$1,$2,$3,$4,$2+$3+$4}' pay.txt

(2)过滤第一列大于2的行

$ awk '$1>2' log.txt
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo

(3)过滤第一列等于2的行

$ awk '$1==2 {print $1,$3}' log.txt
#输出
2 is

(4)过滤第一列大于2并且第二列等于’Are’的行

$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt
#输出
3 Are you

9.使用循环语句
(1)输出每行的前5列,并按行输出

awk '{for(i=1;i<6;i++)printf("%s ",$i);printf("\n")}' input.file

(2)输出多列,并更改分隔符为TAB

awk '{for(i=2;i<=NF;i++)printf("%s\t",$i);printf("\n")}' input.file

(3)每三行作为一列输出

awk '{if(NR%3 != 0){ORS="\t"}else{ORS="\n"}print}' input.file

(4)打印九九乘法表文章来源地址https://www.toymoban.com/news/detail-493560.html

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

到了这里,关于awk命令的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Windows基础命令:目录和文件操作&文本处理&网络相关操作

    方法一:打开\\\"运行\\\"对话框(Win+R),输入cmd 也可以通过cmd /c 命令和cmd /k 命令的方式来直接运行命令(/c表示执行完命令后关闭cmd窗口;/k表示执行完命令后保留cmd窗口) 方法二:在任务栏直接搜索“cmd” 显示当前目录或改变当前目录 语法规则 (1)显示目录 显示当前驱动

    2024年02月05日
    浏览(43)
  • Linux命令小技巧:显示文件指定行的内容

    工作中会有很多千奇百怪的需求,比如:如何在 Linux 命令行中快速找到某个文件的第 n 行?如何显示从第 x 行到第 y 行之间的内容? 想要实现以上效果,其实有很多办法可以实现。 比如,假如要显示第 13 行内容,可以使用 head 命令组合 tail 命令,如下: 例如: 输出: 或者

    2024年02月11日
    浏览(52)
  • 一个超级大的文件如何更快读

    问题起因 一个有千万的数据的txt文件如何发挥IO的全部性能更快的读和写。 使用ChatGPT4的方案 在C#中,我们可以使用多线程来处理大量的数据并将其写入数据库。在处理大数据时,我们需要将任务分解为多个子任务,这样我们可以在不同的线程中并行执行它们以提高性能。

    2024年02月08日
    浏览(37)
  • 瘦身.git,处理项目中.git文件夹过大的问题

    出现原因: .git文件主要用来记录每次提交的变动,当我们在提交时包含大文件时,会被git记录下来, .git文件越来越大、越来越繁重。。。 一:将项目切换至master分支 二:删除存储的大文件 方法(1): 方法(2):前提是知道要删除的大文件 三:查看瘦身后的.git文件大小

    2024年02月16日
    浏览(51)
  • 处理podman的overlay-containers中ctr.log日志文件过大的问题

    公司服务器的一些软件使用了容器技术,比如Podman、Docker,从架设到现在已经稳定运行了1年半了,半年前发现磁盘占用比较大, /var/lib/containers 占用了260G的磁盘空间,重启了一下容器,磁盘空间降下来了不少,同时由于这个目录下存的都是容器的磁盘文件,不能乱动,所以

    2024年02月08日
    浏览(42)
  • 【linux命令讲解大全】025.mtools - 一个强大的MS-DOS文件系统工具

    显示mtools支持的指令 补充说明 mtools 命令用于显示mtools支持的指令。 mtools 是一个模拟MS-DOS文件系统的工具程序,可以执行许多与MS-DOS相关的操作。这些指令都是 mtools 的符号连接(symbolic links),因此它们具有一些共同的特性。 语法 选项 -a :当遇到长文件名重复时,自动更

    2024年02月11日
    浏览(41)
  • 【Python小工具】解决Python的Pyinstaller将.py文件打包成.exe可执行文件后文件过大的问题

    在文章 【Python小项目】Python的GUI库Tkinter实现随机点名工具或抽奖工具并封装成.exe可执行文件中我们实现了一个python小项目的制作并将其打包成了.exe可执行文件。但是,当我们查看了一下文件大小后,好家伙,一百多行代码打包完竟然有242M。于是,我们静下心来思考,是不

    2024年02月10日
    浏览(56)
  • linux awk文本

    目录 一、awk概念 二、awk的工作过程 三、awk字符 四、内置变量 五、getline  六、awk的精准筛选 七、例子演示 八、实验演示                           一、awk概念 1.概念:awk 是一个功能强大 的编辑工具,逐行读取输入文本,主要作用于文件内容,AWK信息的读入也是逐行指

    2024年02月08日
    浏览(46)
  • 文本三剑客之 awk

    Linux/UNIX 系统中,awk 是一个功能强大的编辑工具。逐行读取输入文本 以空格作为分割符,多个空格他会自动压缩成一个空格 AWK信息的读入也是逐行指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理. 1按照命令找指定的行  2.找到的行 打印,操作 awk

    2024年02月08日
    浏览(42)
  • Linux文本三剑客---awk

    Linux文本三剑客之一(grep,sed,awk),功能最强大的文本工具。 逐行读取输入的文本内容,默认以空格和tab键作为分隔符。但是多个空格或者tab键的空格,会自动压缩成一个,然后按照指定的模式和条件执行编辑命令 可以在免交互的情况下,实现复杂的文本操作。完成自动化配

    2024年02月07日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包