cmd_sed_grep_awk

sed 可以实现非交互式的字符串替换,grep 能够实现有效的过滤功能。与两者相比,awk 是一款强大的文本分析工具,在对数据分析并生成报告时,显得尤为强悍。

linux三剑客之sed

介绍

sed(stream editor),流编辑器,用程序的方式来编辑文本,与 vim 的交互式编辑方式截然不同。它的功能十分强大,加上正则表达式的支持,可以进行大量的复杂文本的编辑操作。

使用场景:

  • 自动化程序中,不适合交互方式编辑的;
  • 大批量重复性的编辑需求;
  • 编辑命令太过复杂,在交互文本编辑器难以输入的情况;

工作原理

sed 作为一种非交互式编辑器,它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后输出编辑结果。

简单描述 sed 工作原理:

  • sed 从输入文件中读取内容,每次处理一行内容,并把当前的一行内容存储在临时的缓冲区中,称为 模式空间
  • 接着用 sed 命令处理缓存区中的内容;
  • 处理完毕后,把缓存区的内容送往屏幕;
  • 接着处理下一行;

这样不断重复,直到文件末尾,文件内容并没有改变,除非你使用重定向输出或指定了 i 参数

正则表达式

sed 基本上就是在玩正则表达式模式匹配,故简单介绍下正则表达式的基本内容。

基本正则表达式

  • .,表示匹配任意一个字符,除了换行符,类似 Shell 通配符中的 ?
  • *,表示前边字符有 0 个或多个;
  • .*,表示任意一个字符有 0 个或多个,也就是能匹配任意的字符;
  • ^,表示行首,也就是每一行的开始位置,^abc 匹配以 abc 开头的字符串;
  • $,表示行尾,也就是每一行的结尾位置,}$ 匹配以大括号结尾的字符串;
  • {},表示前边字符的数量范围,{2},表示重复 2 次,{2,}重复至少 2次,{2,4} 重复 2-4 次;
  • [],括号中可以包含表示字符集的表达式,使用方法大概如下几种
表达式 含义
[a-z] 表示a-z字符中的一个,也就是小写字母
[0-9] 表示0-9字符中的一个,也就是表示数字
[A-Z] 表示A-Z字符中的一个,也就是大写字幕
[abc] 表示字符a或字符b或字符c
[^0-9] 表示非数字类型的字符

扩展正则表达式

扩展正则表达式使用频率上没有基本表达式那么高,但依然很重要,很多情况下没有扩展正则是搞不定的,sed 命令使用扩展正则时需要加上选项 -r

  • ?:表示前置字符有 0 个或 1 个;
  • +:表示前置字符有 1 个或多个;
  • |:表示匹配其中的一项即可;
  • ():表示分组,(a|b)b 表示可以匹配 ab 或 bb 子串,且命令表达式中可以通过 \1\2 来表示匹配的变量
  • {}:和基本正则中的大括号中意义相同,只不过使用时不用加 转义符号;

基本语法

sed [选项] ‘command‘ filename

选项部分,常见选项包括:-n-e-i-f-r 等。

选项简单说明:

  • -n,表示安静模式。默认 sed 会把每行内容处理完毕后打印到屏幕上,加上选项后就不会输出到屏幕上。
  • -e,如果需要用 sed 对文本内容进行多种操作,则需要执行多条子命令来进行操作;
  • -i,默认 sed 只会处理模式空间的副本内容,不会直接修改文件,如果需要修改文件,就要指定 -i 选项;
  • -f,如果命令操作比较多时,用 -e 会有点力不从心,这时需要把多个子命令写入脚本文件,使用 -f 选项指定执行该脚本;
  • -r:如果需要支持扩展正则表达式,那么需要添加 -r 选项;

command子命令格式:

[地址1, 地址2] [函数] [参数(标记)]

如sed ‘2,4s/hello/A/g‘ file.txt
2,4是地址			:第2行到第4行
s/hello/A是函数	:把hello替换为A
g是参数			:替换一行所有匹配到的

数字定址和正则定址

默认情况下 sed 会对每一行内容进行匹配、处理、输出,有时候我们不需要对所有内容进行操作,只需要修改一部分,比如 1-10 行,偶数行,或包括 hello 字符串的行。

这种情况下,就需要我们去定位特定的行来进行处理,而不是全部内容,这里把定位指定的行叫做定址。

数字定址

数字定址其实就是通过数字去指定要操作的行,有几种方式,每种方式都有不同的应用场景。

# 只将第4行中hello替换为A
$ sed ‘4s/hello/A/g‘ file.txt
# 将第2-4行中hello替换为A
$ sed ‘2,4s/hello/A/g‘ file.txt
# 从第2行开始,往下数4行,也就是2-6行
$ sed ‘2,+4s/hello/A/g‘ file.txt
# 将最后1行中hello替换为A
$ sed ‘$s/hello/A/g‘ file.txt
# 除了第1行,其它行将hello替换为A
$ sed ‘1!s/hello/A/g‘ file.txt

正则定址

正则定址,是通过正则表达式的匹配来确定需要处理编辑哪些行,其它行就不需要处理

# 将匹配到hello的行执行删除操作,d 表示删除
$ sed ‘/hello/d‘ file.txt
# 删除空行,"^$" 表示空行
$ sed ‘/^$/d‘ file.txt
# 将匹配到以ts开头的行到以te开头的行之间所有行进行删除
$ sed ‘/^ts/,/^te/d‘ file.txt

(三)数字定址和正则定址混用

数字定址和正则定址可以配合使用

# 匹配从第1行到ts开头的行,把匹配的行执行删除
$ sed ‘1,/^ts/d‘ file.txt

基本子命令

替换子命令s

子命令 s 为替换子命令,是平时 sed 使用最多的命令,因为支持正则表达式,功能很强大,基本可以替代 grep 的基本用法。

基本语法:

[address]s/pat/rep/flags

替换子命令基本用法

# 将每行的hello替换为HELLO,只替换匹配到的第一个
$ sed ‘s/hello/HELLO/‘ file.txt
# 将匹配到的hello全部替换为HELLO,g表示替换一行所有匹配到的
$ sed ‘s/hello/HELLO/g‘ file.txt
# 将第2次匹配到的hello替换
$ sed ‘s/hello/A/2‘ file.txt
# 将第2次后匹配到的所有都替换
$ sed ‘s/hello/A/2g‘ file.txt
# 在行首加#号
$ sed ‘s/^/#/g‘ file.txt
# 在行尾加东西
$ sed ‘s/$/xxx/g‘ file.txt

正则表达式的简单使用

# 使用扩展正则表达式,结果为:A
$ echo "hello 123 world" | sed -r ‘s/[a-z]+ [0-9]+ [a-z]+/A/‘

# <b>This</b> is what <span style="x">I</span> meant
# 要求:去掉上述html文件中的tags,结果为:This is what I meant
$ sed ‘s/<[^>]*>//g‘ file.txt

多个匹配

# 将1-3行的my替换为your,且3行以后的This替换为That
$ sed ‘1,3s/my/your/g; 3,$s/This/That/g‘ my.txt
# 等价于
$ sed -e ‘1,3s/my/your/g‘ -e ‘3,$s/This/That/g‘ my.txt

使用匹配到的变量

# 将匹配到的字符串前后加双引号,结果为:My "name" chopin
# "&"表示匹配到的整个结果集
$ echo "My name chopin" | sed ‘s/name/"&"/‘

# 如下命令,结果为:hello=world,"\1"和"\2"表示圆括号匹配到的值
$ echo "hello,123,world" | sed ‘s/\([^,]\),.*,\(.*\)/\1=\2/‘

其它几个常见用法

# 只将修改匹配到行内容打印出来,-n关闭了模式空间的打印模式
$ sed -n ‘s/i/A/p‘ file.txt

# 替换是忽略大小写,将大小写i替换为A
$ sed -n ‘s/i/A/i‘ file.txt

# 将替换后的内容另存为一个文件
$ sed -n ‘s/i/A/w b.txt‘ file.txt
$ sed -n ‘s/i/A/‘ file.txt > b.txt

注意,sed 修改匹配到的内容后,默认行为是不保存到原文件,直接输出修改后模式空间的内容,如果要修改原文件需要指定 -i 选项。

追加行子命令a

子命令 a 表示在指定行下边插入指定的内容行;

# 将所有行下边都添加一行内容A
$ sed ‘a A‘ file.txt
# 将文件中1-2行下边都添加一行内容A
$ sed ‘1,2a A‘ file.txt

插入行子命令i

子命令 ia 使用基本一样,只不过是在指定行上边插入指定的内容行

# 将文件中1-2行上边都添加一行内容A
$ sed ‘1,2i A‘

替换行子命令c

子命令 c 是表示把指定的行内容替换为自己需要的行内容

# 将文件所有行都分别替换为A
$ sed ‘c A‘ file.txt
# 将文件中1-2行内容替换为A,注意:两行内容变成了一行A
$ sed ‘1,2c A‘ file.txt
# 将1-2行内容分别替换为A行内容
$ sed ‘1,2c A\nA‘ file.txt

删除行子命令d

子命令 d 表示删除指定的内容行,这个很容理解

# 将文件中1-3行内容删除
$ sed ‘1,3d‘ file.txt
# 将文件中This开头的行内容删除
$ sed ‘/^This/d‘ file.txt

设置行号子命令=

子命令 =,可以将行号打印出来

# 将指定行上边显示行号
$ sed ‘1,2=‘ file.txt
# 可以将行号设置在行首
$ sed ‘=‘ file.txt | sed ‘N;s/\n/\t/‘

子命令N

子命令 N,把下一行内容纳入当缓存区做匹配,注意的是第一行的 \n 仍然保留

其实就是当前行的下一行内容也读进缓存区,一起做匹配和修改,举个例子吧

# 将偶数行内容合并到奇数行
$ sed ‘N;s/\n//‘ file.txt

实战练习

掌握了上边的基础命令操作后,基本上可以满足平时 95% 的需求啦。sed 还有一些高级概念,比如:模式空间、保持空间、高级子命令、分支和测试等,平时使用概率非常小,本文就暂不讲解了,有需要的同学可以私信我一起交流学习哈。

学习了这么多基础用法后,只要你勤加练习,多实践,多使用,一定可以得心应手,极大提高的文本处理效率。下边我简单再给出一些比较实用的操作实践,希望对大家有帮助。

1. 删除文件每行的第二个字符

$ sed -r ‘s/(.)(.)(.*)$/\1\3/‘ file.txt

2. 交换每行的第一个字符和第二个字符

$ sed -r ‘s/(.)(.)(.*)/\2\1\3/’ file.txt

3. 删除文件中所有的数字

$ sed ‘s/[0-9]//g‘ file.txt

4. 用制表符替换文件中出现的所有空格

$ sed -r ‘s/ +/\t/g‘ file.txt

5. 把所有大写字母用括号()括起来

$ sed -r ‘s/([A-Z])/(\1)/g‘

6. 隔行删除

$ sed ‘0~2{d}‘ file.txt

7. 删除所有空白行

$ sed ‘/^$/d‘ file.txt

linux三剑客之grep

grep 命令是一种强大的文本搜索工具,它能使用正则表达式,按照指定的模式去匹配,并把匹配的行打印出来。需要注意的是,grep 只支持匹配而不能替换匹配的内容,替换的功能可以由 sed 来完成。

示例实战

本文中的示例,需要一个样例文件,文件内容如下

book@100ask:~$ cat g.txt
0root:x:0:0:root:/root:/bin/zsh
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
syslog:x:104:108::/home/syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false
sshd:x:109:65534::sshd:/usr/sbin/nologin

1.把包含syslog的行过滤出来

book@100ask:~$ grep "syslog" g.txt
syslog:x:104:108::/home/syslog:/bin/false

#忽略大小写
book@100ask:~$ grep -i "SYSLOG" g.txt
syslog:x:104:108::/home/syslog:/bin/false

2.把以ntp开头的行过滤出来

book@100ask:~$ grep "^ntp" g.txt
ntp:x:108:114::/home/ntp:/bin/false

#把false结尾的行过滤出来
book@100ask:~$ grep "false$" g.txt
syslog:x:104:108::/home/syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false

3.把匹配ntp的行以及下边的两行过滤出来

book@100ask:~$ grep -A2 "syslog" g.txt
syslog:x:104:108::/home/syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false
sshd:x:109:65534::sshd:/usr/sbin/nologin

4.把包含syslog及上边的一行过滤出来

book@100ask:~$ grep -B1 "syslog" g.txt
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
syslog:x:104:108::/home/syslog:/bin/false

5.把包含syslog以及上、下一行内容过滤出来

book@100ask:~$ grep -C1 "syslog" g.txt
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
syslog:x:104:108::/home/syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false

6.过滤某个关键词,并输出行号

book@100ask:~$ grep -n "ntp" g.txt
4:ntp:x:108:114::/home/ntp:/bin/false

7.过滤不包含某关键词,并输出行号

book@100ask:~$ grep -n -v "sbin" g.txt
1:0root:x:0:0:root:/root:/bin/zsh
3:syslog:x:104:108::/home/syslog:/bin/false
4:ntp:x:108:114::/home/ntp:/bin/false

8.删除掉空行

book@100ask:~$ grep -v "^$" g.txt
# "^$"表示空行

9.过滤包含root或syslog的行

# 用"-e"实现多选项间逻辑or关系
book@100ask:~$ grep -e "root" -e "syslog" g.txt
0root:x:0:0:root:/root:/bin/zsh
syslog:x:104:108::/home/syslog:/bin/false
# 等价于
$ grep -E "root|syslog" g.txt

10.查看当前目录中包含某关键词的所有文件(很有用)

# -r表示在当前目录递归查询
book@100ask:~$ grep -r "font" .
#一般会用下边的命令,会更加有效(显示行号,且以单词严格匹配)
book@100ask:~$ grep -rnw "font" .
#在递归的过程中排除某些目录
book@100ask:~$ grep -rnw --exclude-dir={.git,svn} "mail"

简单总结

  • -A:除了匹配行,额外显示该行之的N行
  • -B:除了匹配行,额外显示该行之的N行
  • -C:除了匹配行,额外显示该行前后的N行
  • -c:统计匹配的行数
  • -e实现多个选项间的逻辑 or 关系
  • -E支持扩展的正则表达式
  • -F:相当于 fgrep
  • -i忽略大小写
  • -n:显示匹配的行号
  • -o:仅显示匹配到的字符串
  • -q:安静模式,不输出任何信息,脚本中常用
  • -s:不显示错误信息
  • -v显示不被匹配到的行
  • -w:显示整个单词
  • --color:以颜色突出显示匹配到的字符串

linux三剑客之awk

场景

awk 能干些什么事情:

1.能够将给定的文本内容,按照我们期望的格式输出显示,打印成报表。

2.分析处理系统日志,快速地分析挖掘我们关心的数据,并生成统计信息;

3.方便地用来统计数据,比如网站的访问量,访问的 IP 量等;

4.通过各种工具的组合,快速地汇总分析系统的运行信息,让你对系统的运行了如指掌;

5.强大的脚本语言表达能力,支持循环、条件、数组等语法,助你分析更加复杂的数据;

......

当然 awk 不仅能做这些事情,当你将它的用法融汇贯通时,可以随心所欲的按照你的意愿,来进行高效的数据分析和统计。

不过我们需要知道,awk 不是万能的,它比较擅长处理格式化的文本,比如 日志、csv 格式数据等;

原理

我们先来简单了解 awk 基本工作原理,通过下边的图文讲述,希望你能了解 awk 到底是如何工作的。

awk 基本命令格式

awk ‘BEGIN{cmds} pattern{cmds} END{cmds}‘

结合下图来详细说明 awk 工作原理

cmd_sed_grep_awk

  • 首先,执行关键字 BEGIN 标识的 {} 中的命令;
  • 完成 BEGIN 大括号中命令的后,开始执行 body 命令;
  • 逐行读取数据,默认读到 \n 分割的内容为一条 记录,其实就是的概念;
  • 记录按照指定的分隔符划分为 字段,其实就是的概念;
  • 循环执行 body 块中的命令,每读取一行,执行一次 body,最终完成 body 执行;
  • 最后,执行 END 命令,通常会在 END 中输出最后的结果;

awk 是输入驱动的,有多少输入行,就会执行多少次 body 命令。

我们在下边的示例学习中,要时刻记着:记录 (Record) 就是字段 (Field) 就是BEGIN 是预处理阶段,body 是 awk 真正工作的阶段,END 是最后处理阶段。

实战 - 入门

从下边内容开始,我们直接进入到实战。为了方便举例,我先把如下信息保存到 file.txt

-rw-------  1 book book 21962 Jun 24 05:38 .ICEauthority
drwx------  5 book book  4096 Nov  2  2020 .local/
drwxrwxr-x  2 book book  4096 Dec 15  2020 lpr/
drwx------  5 book book  4096 Mar 26  2019 .mozilla/
drwxr-xr-x  2 book book  4096 Mar 26  2019 Music/
-rw-r--r--  1 book book 49975 Sep 11  2020 my_video-1.mkv
drwxrwxrwx  3 root root  4096 Nov 19  2020 nfs_rootfs/
drwxr-xr-x  2 book book  4096 Mar 26  2019 Pictures/
drwx------  3 book book  4096 Sep  9  2020 .pki/
-rw-r--r--  1 book book   807 Mar 26  2019 .profile
drwxr-xr-x  2 book book  4096 Mar 26  2019 Public/
-rw-------  1 book book    27 Dec 15  2020 .python_history
drwxr-xr-x  8 book book  4096 Sep  2  2020 Qt5.12.1/
drwxr-xr-x  8 book book  4096 Aug 23  2020 Qt5.6.0/
drwxr-xr-x  7 book book  4096 Aug 24  2020 qtcreator-4.8.0/
drwxr-xr-x 49 book book  4096 Mar 11 01:07 Qtproj/

我们先来一个最简单最常用的 awk 示例,输出第 1、4、8 列:

awk ‘{print $1,$4,$8}‘ test.txt

大括号里边的就是 awk 语句,只能被单引号包含,其中,$1..$N表示第几列,$0 表示整个行内容

再来看下 awk 比较实用的功能 格式化输出。和 C 语言的 printf 格式输出是一毛一样。

awk ‘{printf "%-4s %-4s %-6s %-8s\n",$1,$2,$4,$8}‘ test.txt

%s 表示字符串占位符,-4表示列宽度为 4,且左对齐,我们还可以根据需要,列出更复杂的格式来,这里先不详细举例了。

实战 - 进阶

(一)过滤记录

有些数据可能不是你想要的,可以根据需要进行过滤

awk ‘$3 == "root" && $7 == 19 {print $0}‘ test.txt

上边的过滤条件为,第 3 列为 root 且第 7 列为 19 的行,才会被输出。

awk 支持各种比较运算符号 !=><>=<=,其中 $0 表示整行的所有内容。

(二)内置变量

awk 内置了一些变量,更方便我们对数据的处理

awk ‘$3 == "root" || NR == 2 {printf("%2s %s %10s\n",NR,$1,$NF)}‘ test.txt

过滤第 3 列为 root 用户,以及第 2 行内容,且打印时输出行号。NR 表示当前第几行,NF表示当前行有几列。

(三)指定分隔符

我们的数据,不总是以空格为分隔符,我们可以通过 FS 变量指定分隔符。

awk ‘BEGIN{FS="2019"} {print $1," * ",$2}‘ test.txt

我们指定分隔符为 2019,这样就将行内容分割为了两部分,将 2019 替换成了 *

上边的命令也可以通过 -F 选项指定分割符

awk -F‘2019‘ ‘{print $1," * ",$2}‘ test.txt

如果你需要指定多个分隔符,可以这样做 -F ‘[;:]‘

同样,awk 可以指定输出时的分隔符,通过 OFS 变量来设置

awk ‘{print $1,$2,$3,$4,$5,$6,$7,$8}‘ OFS=";" test.txt

输出时,各字段用 OFS 指定的符号进行了分隔。

实战 - 高级

(一)条件匹配

列出 root 用户的所有文件,以及第一行文件

awk ‘$3 ~ /root/ || NR ==1 {print NR,$0}‘ test.txt

上边匹配第三列中包含 root 的行,~ 其实就是正则表达式的匹配。

同样,awk 可以像 grep 一样匹配某一行,就像这样

awk ‘/Aug/‘ test.txt

另外,可以这样 /Aug|Dec/ 匹配多个关键词。

模式取反可以使用 ! 符号

awk ‘$3 !~ /root/ {print $0}‘ test.txt
awk ‘!/Aug/‘ test.txt

(二)拆分文件

我们来做一件有意思的事情,可以将文本信息拆分为多个文件,下边命令按照月份(第5列)将文件信息拆分为多个文件

awk ‘{print $0 > $6}‘ test.txt

awk 支持重定向符号 >,直接将每行内容重定向到月份命名的文件了,当然你也可以把指定的列输出到文件

(三)if 语句

复杂的条件判断,可以使用 awk 的 if 语句,awk 的强大正因为它是个脚本解释器,拥有一般脚本语言的编程能力,下边示例通过稍微复杂的条件进行拆分文件

awk ‘{if($3 == "root") print > "root.txt"; 		else if($3 == "dave") print > "dave.txt"; 		else print > "mary.txt"}‘ test.txt

要注意,if 语句是在大括号里边的。

(四)统计

统计当前目录下,所有 *.c*.h 文件所占用空间大小总和

ls -l *.c *.h | awk ‘{sum+=$5} END{print sum}‘

第 5 列表示文件大小,每读取一行就会将该文件大小计算到 sum 变量中,在最后 END 阶段打印出 sum,也就是所有文件的大小总和。

再来看一个例子,统计每个用户的进程占用了多少内存,注意取值的是 RSS 那一列

ps aux | awk ‘NR!=1 {a[$1]+=$6} END{for(i in a) print i,a[i]}‘

这里用到了 数组for 循环,值得一提的是,awk 的数组可以理解为字典或 Map,key 可以是数值和字符串,这种数据类型在平时很常用。

(五)字符串

通过下边简单示例,展示 awk 对字符串操作的支持

awk ‘{if(length($4) == 4) print $2,toupper($3)}‘ test.txt

awk 内置支持一系列的字符串函数,length 计算字符串长度,toupper 函数转换字符串为大写。

实战 - 技巧

为了从整体上理解 awk 工作机制,我们再来看一个综合的示例,假设有一个学生成绩单:

book@100ask:~/test$ 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 的执行方式,我们的 awk 脚本如下:


#!/bin/awk -f
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 结果如下

book@100ask:~/test$ 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

我们可以将复杂的 awk 语句写入脚本文件 cal.awk,然后通过 -f 选项指定从脚本文件执行。

  • BEGIN 阶段,我们初始化了相关变量,并打印了表头的格式
  • body 阶段,我们读取每一行数据,计算该学科和该同学的总成绩
  • END 阶段,我们先打印了表尾的格式,并打印总成绩,以及计算了平均值

这个简单示例,完整的体现了 awk 的工作机制和原理。

总结归纳

通过上述的示例,我们学习到了 awk 的工作原理,下边我们来总结下几个概念和常用的知识点。

(一)内置变量

1. 每一行内容记录,叫做记录,英文名称 Record

2. 每行中通过分隔符隔开的每一列,叫做字段,英文名称 Field

明确这几个概念后,我们来总结几个重要的内置变量:

  • NR:表示当前的行数;
  • NF:表示当前的列数;
  • RS:行分隔符,默认是换行;
  • FS:列分隔符,默认是空格和制表符;
  • OFS:输出列分隔符,用于打印时分割字段,默认为空格
  • ORS:输出行分隔符,用于打印时分割记录,默认为换行符

(二)输出格式

awk 提供 printf 函数进行格式化输出功能,具体的使用方式和 C 语法基本一致。

基本用法

printf("%12s,%02d,%0.2f\n",s,d,g);

常用的格式化方式:

  • %d 十进制有符号整数
  • %u 十进制无符号整数
  • %f 浮点数
  • %s 字符串
  • %c 单个字符
  • %e 指数形式的浮点数
  • %x %X 无符号以十六进制表示的整数
  • %0 无符号以八进制表示的整数
  • %g 自动选择合适的表示法
  • \n 换行符
  • \t Tab符

(三)编程语句

awk 不仅是一个 Linux 命令行工具,它其实是一门脚本语言,支持程序设计语言所有的控制结构,它支持:

  • 条件语句
  • 循环语句
  • 数组
  • 函数

(四)常用函数

awk 内置了大量的有用函数功能,也支持自定义函数,允许你编写自己的函数来扩展内置函数。

这里只简单罗列一些比较常用的字符串函数:

  • index(s, t) 返回子串 t 在 s 中的位置
  • length(s) 返回字符串 s 的长度
  • split(s, a, sep) 分割字符串,并将分割后的各字段存放在数组 a 中
  • substr(s, p, n) 根据参数,返回子串
  • tolower(s) 将字符串转换为小写
  • toupper(s) 将字符串转换为大写

转载自:

https://mp.weixin.qq.com/s/xlQZ5aE7tr3yk-9sHpbabw

cmd_sed_grep_awk

上一篇:图书管理系统前端页面搭建


下一篇:Redis入门不难系列(1)