Linux笔记 No.26---(文本三剑客之sed、awk)

文章目录

一、sed

sed是一种新型的,非交互式的流编辑器,它能执行与编辑器 vi 和 ex 相同的编辑任务。sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。

工作原理:

sed 编辑器逐行处理文件(或输入),并将输出结果发送到屏幕。 sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为“模式空间”或“临时缓冲”。sed 处理完模式空间中的行后(即在该行上执行sed 命令后),就把改行发送到屏幕上(除非之前有命令删除这一行或取消打印操作),执行下一个循环。 sed 每处理完输入文件的最后一行后, sed 便结束运行。 sed 把每一行都存在模式空间中,对这个副本进行编辑,所以不会修改或破坏原文件

它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。

如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或者-i进行修改。

功能:

主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等;对文本按处理

用法:

sed [选项]... '地址界定 处理动作' 文件...
或
前置命令 | sed [选项] '地址界定 处理动作’

常用选项:

  • -n:不输出模式空间内容到屏幕,即不自动打印
  • -e: 多点编辑
  • -f /PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本 这里的编辑脚本每行一个不需要带引号
  • -r: 支持使用扩展正则表达式 regexp-extended
  • -i:直接将处理的结果写入文件

正常情况下,sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不
会对原始文件做任何更改。若希望直接修改文件内容,应添加选项 -i 。为了避免生产环境中因误操作导
致系统故障,使用时要谨慎

script:地址定界编辑命令

  • 地址定界:

(1)空地址:对全文进行处理

(2)单地址:

			# 					:指定第#行
			/pattern/			:被此模式所匹配到的每一行

(3)地址范围:

			num1,num2					:从第num1行到num2行
			num3,+num					:从第num3行开始后的共num行的所有行(包括第num3行)
			num4,/pattern1/			    :从第num4行到模式1匹配到的行的所有行
			/pattern2/,/pattern3/		:从模式2匹配到的内容行直到模式3匹配到的内容行的所有行
			$							:最后一行;

(4) 步进:~

			1~2:所有奇数行
			2~2:所有偶数行
  • 处理动作(编辑命令):
d						:删除;
p						:显示模式空间中的内容;
a \text					:在行后面追加文本“text”,支持使用\n实现多行追加;
i \text					:在行前面插入文本“text”,支持使用\n实现多行插入;
c \text					:把匹配到的行替换为此处指定的文本“text”;
w /PATH/TO/SOMEFILE		:保存模式空间匹配到的行至指定的文件中;
r /PATH/FROM/SOMEFILE	:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并;
=						:为模式匹配到的行打印行号;
!						:条件取反;

s/old/new/替换标记			:查找替换,将指定范围内的old字符串替换成old字符串。其分隔符可自行指定,常用的有s@@@, s###等;
s/old/new/      			:将每行匹配到的第一个old替换为new
s/old/new/NUM  				:将每行匹配到的第NUM个old替换成new
s/old/new/g					:将所有的old替换成 new 
	
	替换标记:
		g						:全局替换;
		w /PATH/TO/SOMEFILE		:将替换成功的结果保存至指定文件中;
		p						:显示替换成功的行;
		NUMg				:替换每一行指定第NUM个以及NUM个以后

综述:地址界定即为address-range1|pattern-range1 [address-range2|pattern-range2]

  • address-range
  • address-range1,address-range2
  • address-range,pattern-range
  • pattern-range
  • pattern-range1,pattern-range2
  • pattern-range,address-range

1.模式匹配(正则)

[root@eddy  ~]# sed -n '/^root.*bash$/ p' /etc/passwd
root:x:0:0:root:/root:/bin/bash

2.打印/etc/passwd文件所有内容

 sed -n 'p' /etc/passwd

3.将root替换成tree并输出

[root@eddy  ~]# sed -n 's/root/tree/ p' /etc/passwd
tree:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/tree:/sbin/nologin

4.多点编辑

[root@eddy  ~]# sed -n -e '/^root/ p' -e '/^apache/ p' /etc/passwd

5.打印第1行内容

[root@eddy ~]# sed -n '1 p' /etc/passwd

6.打印第10行至最后一行的内容

[root@eddy ~]# sed -n '10,$ p' /etc/passwd

7.打印第3行至所匹配内容行之间的内容(左右均为闭区间)

[root@eddy ~]# sed -n '3,/root/ p' passwd

如果直至文件最后都未匹配到root,那么便会输出第3行至文件最后一行的所有内容

sed -n '/pattern/,NUM p' FILENAME
  • 如果pattern模式未匹配到内容,将不会有任何输出
  • 如果pattern匹配到的行的行号大于NUM,那么只会输出pattern所匹配到的行
  • 如果pattern匹配到的行的行号小于NUM,那么便会输出pattern匹配到的行至NUM行的所有行

8.在匹配到的行或第NUM行前插入指定内容:

[root@eddy ~]# sed '/pattern/ i 插入内容'  文件名
或
[root@eddy ~]# sed 'NUM i 插入内容'  文件名

9.将匹配到的行或第NUM行的内容进行重新指定:

[root@eddy ~]# sed '/pattern/ c 修改后的内容'  文件名
或
[root@eddy ~]# sed 'NUM c 修改后的内容'  文件名

10.打印出文件中有指定范围中的某个字段:

[root@eddy ~]# sed -n '/内容1\|内容2/p' 文件名

11.打印第NUM1行至NUM2行的所有内容:

[root@eddy ~]# sed -n 'NUM1,NUM2 p' 文件名

12.打印从第NUM行开始步长为STEP的行的内容:

sed -n 'NUM~STEP' 文件名   

13.从指定的脚本文件中读取对文本的处理动作(编辑脚本中每行一条且不需要带引号)

sed -n -f 脚本名 文件名

eg:

[root@eddy ~]# cat script.sed
/^root/ p
/^apache/ p
[root@eddy ~]# sed -n -f script.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

14.对地址界定进行取反(!)

sed [option] '地址界定 ! 处理动作 ' FILENAME

eg:

[root@eddy ~]# cat passwd 
dxk:x:1000:1000::/home/dxk:/bin/bash
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
test:x:1001:1001::/home/test:/bin/bash
bob:x:1002:1002::/home/bob:/bin/bash
tcpdump:x:72:72::/:/sbin/nologin
[root@eddy ~]# sed -n '/dxk/,3 ! p' passwd 
nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
test:x:1001:1001::/home/test:/bin/bash
bob:x:1002:1002::/home/bob:/bin/bash
tcpdump:x:72:72::/:/sbin/nologin

15.将处理后的行写入文件

sed [选项] ‘地址界定 w filename’ FILENAME	#(只将有改动的行写入文件)

16.删除第NUM行内容

sed  'NUM d' FILENAME

17.删除指定行范围内的内容

sed 'NUM1,NUM2 d' FILENAME

18.删除指定模式匹配到的内容

sed '/pattern/ d' FILENAME
sed 'NUM,/pattern/ d' FILENAME
sed '/pattern/,NUM d' FILENAME
sed '/pattern1/,/pattern2/ d' FILENAME

19.删除第NUM行(或模式匹配到的行)及以下num行

sed  'NUM,+num d' FILENAME
或
sed '/pattern/,+num d' FILENAME

注意:没有-num

20.删除空行:

sed '/^$/ d' FILENAME 

21.删除注释行:

sed '/^#/ d' FILENAME

22…替换

用法:sed [选项] ‘[地址界定] s/要替换的字符串/替换后的字符串/[替换标记]’ 文件名

将FILENAME文件中的str1字符串替换成为str2
因为替换标记省略未写,所以默认是将匹配到str1行的第一个str1替换成str2,若同一行有两个str1,则只替换第一个

 sed  's/str1/str2/' FILENAME 

全局替换
即将所有匹配到的都进行替换,一行内无论出现多少个str1都被str2替换

sed 's/str1/str2/g' FILENAME

将替换后的所在行写入到指定文件中(文件不存在会创建)

sed -n 's/str1/str2/w filename' FILANAME

只将每行匹配到的第num个str1替换成为str2,并打印出来

sed -n '[地址界定] s/str1/str2/num p' FILENAME

将每行匹配到的第num个及该行后的所有str1替换成为str2,并打印出来

sed -n '[地址界定] s/str1/str2/numg p' FILENAME

&的使用:

[root@eddy ~]# sed -n 's/^roo./<&>/g p' /etc/passwd 
<root>:x:0:0:root:/root:/bin/bash
[root@eddy ~]# echo "This Is a Test.." |sed 's/\([A-Z]\)/(&)/g' 
(T)his (I)s a (T)est..
[root@eddy ~]# echo "This Is a Test.." |sed 's/\([A-Z]\)/\(\1\)/g'
(T)his (I)s a (T)est..

取出/etc/passwd中的所有用户

sed 's/\([^:]*\).*/\1/' /etc/passwd

所有的两位数结尾的行后面都加上 .1

 sed 's/[0-9][0-9]$/&.1/' FILENAME

紧跟在 s 命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符,反斜线除外),只要紧跟在 s 命令,就成了新的串分隔符。这个方法在查找包含正斜杠模式时很管用,例如查找路径名或日期

sed [option] '[地址定界] s#str1#str2#替换标记' FILANAME
sed [option] '[地址定界] s@str1@str2@替换标记' FILENAME
sed [option] '[地址定界] s/str1/str2/替换标记' FILENAME

18.读写入文件

在FILENAME文件的第num行后插入filename文件的内容

sed 'num r filename' FILENAME 

在FILENAME文件的第num1行和num2行后均插入filename文件的内容

sed 'num1,num2 r filename' FILENAME 

将匹配到的文本内容存为另一个文件

sed -n '地址界定 w filename' FILENAME

在匹配到的行的行前插入内容:

sed [选项] '地址界定 i 插入内容' FILENAME

在匹配到的行的行后插入内容:

sed [选项] '地址界定 a 插入内容' FILENAME

将匹配到的行替换为指定内容:

sed [选项] '地址界定 c 替换内容' FILENAME

19.使用sed命令打印出ifconfig ens32的ip地址

[root@eddy ~]# ifconfig ens32 | sed -nr '/\<inet\>/ s/(.*inet )(.*)(netmask.*)/\2/ p'
192.168.126.8 
或
[root@eddy ~]#  ifconfig ens32 | sed -n '2p' | sed -r 's/.*inet (.*)netmask.*/\1/'
192.168.126.8 

20.使用sed命令打印出系统版本

[root@eddy ~]# sed -r -n 's/.*release[[:space:]]*([^.]+).*/\1/p' /etc/redhat-release 
7

21.将文件中的以至少一个空白字符开头的行的行首加#

sed  -n '/^ .*/ s/^/#/ p' FILENAME
或
sed  's/\(^[[:space:]]\)/#\1/g' FILENAME

22.将文件的1~5行进行注释

sed  '1,5 s@^@#@' FILENAME
#要想直接对原文件进行作用并生效,需加-i选项
sed -i  '1,5 s@^@#@' FILENAME

23.将/etc/yum.repos.d/CentOS-Media.repo文件中所有的enabled=0或gpgcheck=0的最后的0修改
为1

sed -i 's/enabled=0/enabled=1/g;s/gpgcheck=0/gpgcheck=1/g' /etc/yum.repos.d/CentOS-
Media.repo

保持空间和模式空间

sed 有两个内置的存储空间:在使用高级命令的时候用到

  • 模式空间:模式空间用于 sed 执行的正常流程中。 该空间 sed 内置的一个缓冲区,用来存放、修改、从输入文件读取的内容。(即对文件的操作都是在模式空间中进行的)
  • 保持空间:保持空间是另外一个缓冲区,用来存放临时数据。 Sed 可以在保持空间和模式空间交换数据,但是不能在保持空间上执行普通的 sed 命令。 我们已经讨论过,每次循环读取数据过程中,模式空间的内容都会被清空,然而保持空间的内容则保持不变,不会在循环中被删除。

高级编辑命令:

h:把模式空间中的内容覆盖至保持空间中;
H:把模式空间中的内容追加至保持空间中;
g:把保持空间中的内容覆盖至模式空间中;
G:把保持空间中的内容追加至模式空间中;
x:把模式空间中的内容与保持空间中的内容互换;
n:覆盖读取匹配到的行的下一行至模式空间中;
N:追加读取匹配到的行的下一行至模式空间中;
d:删除模式空间中的行;
D:删除多行模式空间中的所有行;

对文件进行倒序打印sed '1!G;h;$!d' FILENAME

例:sed ‘1!G;h;$!d’ sedH.txt 执行过程
在这里插入图片描述
1.打印偶数行

sed -n '2~2 p' FILENAME
或
sed -n 'n;p' FILENAME

2.打印文本文件的最后一行

sed  '$!d' FILENAME

3.取出文件后两行

sed  '$!N;$!D' FILENAME	

4.删除原有的所有空白行,而后为所有的非空白行后添加一个空白行

sed  '/^$/d;G' FILENAME

5.显示奇数行

sed  'n;d' FILENAME

6.在原有的每行后方添加一个空白行

sed  'G' FILENAME

7.把第1-3行复制到文件末尾

sed ‘1h;2,3H;$G’ FILENAME

8.把第2行复制第4行

sed '2h;4G'  FILENAME

9.把第1行剪切到文件末尾

sed ‘1h,1d;$G’ FILENAME

10.把第1-2行剪切到文件末尾

sed ‘1h;2H;1,2d;$G’ FILENAME

11.显示/etc/passwd文件中位于第偶数行的用户的用户名

sed -n 'n;p' /etc/passwd | cut -d: -f 1
sed -n '2~2p' /etc/passwd | cut -d: -f 1
sed -n 'n; s/:.*//p' /etc/passwd
sed -n '2~2 s/:.*//p' /etc/passwd
sed -nr 'n; s/(^[^:]+).*/\1/p ' /etc/passwd
sed -nr '2~2 s/(^[^:]+).*/\1/p ' /etc/passwd

二、awk

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用

awk的处理文本和数据时:它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。

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

  • 读输入文件之前执行的代码段(由BEGIN关键字标识)。
  • 主循环执行输入文件的代码段。
  • 读输入文件之后的代码段(由END关键字标识)。
    在这里插入图片描述

1、通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。
2、完成 BEGIN 块的执行,开始执行body块。
3、读入有 \n 换行符分割的记录。
4、将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),$1 表示第一个域,$n 表示第 n 个域。
5、依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。
6、循环读取并执行各行直到文件结束,完成body块执行。
7、开始 END 块执行,END 块可以输出最终结果。

开始块(BEGIN)

语法格式:

BEGIN {awk-commands}

开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。

一般情况下,我们可以在开始块中初始化一些变量。

BEGIN 是 AWK 的关键字,因此它必须是大写的。

注意:开始块部分是可选的,程序可以没有开始块部分。

主体块(BODY)

语法格式:

/pattern/ {awk-commands}

对于每一个输入的行都会执行一次主体部分的命令。

默认情况下,对于输入的每一行,AWK 都会执行命令。但是,我们可以将其限定在指定的模式中。

注意:BODY区域没有用任何关键字表示,只有用正则模式和命令。

结束块(END)

语法格式:

END {awk-commands}

结束块是在程序结束时执行的代码。 END 也是 AWK 的关键字,它也必须大写。 与开始块相似,结束块也是可选的。

用法:

1、第一种,命令行方式:

awk -F ‘/pattern/ {action}’ input-file
  • -F 为字段分界符。如果不指定,默认会使用空格或制表符作为分界符。但如果处理类似passwd文件,此文件各域使用冒号作为分隔符,则必须使用-F选项: awk -F :
  • /pattern/和{action}需要用单引号引起来。
  • /pattern/是可选的。如果不指定, awk 将处理输入文件中的所有行。如果指定一个模式, awk
    则只处理匹配指定的模式的行
  • {action} 为 awk 命令,可以是单个命令,也可以多个命令。整个 action(包括里面的所有命令)都
    必须放在{ 和 }之间。
  • input-file 即为要处理的文件

2、第二种,将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它

3、第三种,将所有awk命令插入一个单独文件,然后调用,如:

awk -f awkscript-file input-file

-f 选项指明在文件 awkscript-file 的 awk 脚本,input-file 是使用 awk 进行浏览的文件名

模式和动作
任何awk语句都是由模式和动作组成,在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。动作即对数据进行的操作,如果省去模式部分,动作将时刻保持执行状态

模式可以是任何条件语句或复合语句或正则表达式,模式包含两个特殊字段BEGIN和END,使用BEGIN语句设置计数和打印头,BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行;END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志,有动作必须使用{}括起来

实际动作在大括号{}内指明,常用来做打印动作,但是还有更长的代码如if和for循环语句等,如果不指明采取什么动作,awk默认打印出所有浏览出的记录

域和记录
awk执行时,其浏览标记为$1,$2…$n,这种方法称为域标记。使用$1,$3表示参照第1和第3域,注意这里使用逗号分隔域,使用$0表示使用所有域。

条件操作符:

操作符含义
~ !~匹配正则表达式 不匹配正则表达式
== != < <= > >=关系运算符
= += -= *= /= %= ^= **=赋值
|或运算
||逻辑或
&与运算
&&逻辑与
++ --增加或减少,作为前缀或后缀
$字段引用
in数组成员

awk内置变量

变量含义
$n当前记录的第n个字段,字段间由 FS分隔。
$0当前记录的内容
ARGC命令行参数个数
ARGV命令行参数排列
ENVIRON支持队列中系统环境变量的使用
FILENAMEawk浏览的文件名
FNR浏览文件的记录数
FS设置输入域分隔符,等价于命令行 -F选项
NF浏览记录的域的个数
NR已读的记录数
OFS输出域分隔符
ORS输出记录分隔符
RS控制记录分隔符

字符串常量

字符串常量描述
\反斜线
\aalert字符,通常为ASCII BEL字符
\b退格键
\f换页
\n换行符
\r回车
\t水平制表符
\v垂直制表符
\xhex digits字符由十六进制数字下面的\x中的字符串来表示
\c字面字符c

awk命令行选项

  • -v :参数传递,定义和引用变量 ,可以把外部变量引入到内部
  • -f :指定脚本
  • -F :指定分隔符
  • -V :查看awk的版本号

print函数和printf函数

awk中同时提供了print和printf两种打印输出的函数。

其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格

print格式: print item1, item2, …
#输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂

printf:格式化输出: printf “FORMAT” , item1, item2, …
必须指定FORMAT
不会自动换行,需要显式给出换行控制符, \n
FORMAT中需要分别为后面每个item指定格式符
printf 格式符:与item一一对应
%c: 显示字符的ASCII码
%d, %i: 显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%: 显示%自身
printf 修饰符:
[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度, %3.1f
-:左对齐(默认右对齐) %-15s
+:显示数值的正负符号 %+d

1.显示最近登录的5个帐号

[root@eddy ~]# last -n 3 | awk  '{print $1}'
root
root
reboot

当读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 “[tab]键”,所以$1表示登录用户,$3表示登录用户ip,以此类推

2.显示所有用户名

awk  -F :  '{print $1}' /etc/passwd

3.显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以制表符分割,同时打印记录号

awk -F : '{print NR, $1"\t"$NF}' /etc/passwd

4.显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"nginx,/sbin/nologin"

awk -F : 'BEGIN{print"USER,BASH"}{print $1","$NF}END{print"nginx,/sbin/nologin"}' /etc/passwd

先执行BEGING操作,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作

5.搜索/etc/passwd有root关键字的所有行

awk -F : '/root/' /etc/passwd

pattern的使用示例,匹配了pattern的行才会执行action(没有指定action,默认输出每行的内容)。搜索支持正则搜索/etc/passwd有root关键字的所有行,并显示对应的shell

6.内置变量NF( 浏览记录的域的个数)

awk -F : '/root/ {print $NF}' /etc/passwd

这里指定action为{print $NF}

7.统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容

awk -F : '{print "filename:"FILENAME,"rownumber:"NR,"columns:"NF",content:"$0}' /etc/passwd

8.使用printf替代print,可以让代码更加简洁,易读

 awk  -F :  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

9.FNR:表示浏览文件的记录数;NR:表示已读的记录数

awk -F: '{print FNR, $0}' /etc/passwd /etc/hosts
awk -F: '{print NR, $0}' /etc/passwd /etc/hosts

每行的列数可用NF即{print NF},那么每行的最后一个域的字段值便可用{print $NF}查看;行号可用NR,即{print NR};FNR表示浏览文件的记录数

10.自定义分隔符

awk -F '[ :\t]' '{print $1,$2,$3}' /etc/passwd 		#指定分隔符为冒号,空格或制表符
#等价于:
awk 'BEGIN{FS="[ :\t]"} {print $1,$2,$3}' /etc/passwd

11.OFS:表示输出域分隔符;ORS:表示输出记录分隔符

#自定义输出域分隔符
awk 'BEGIN{FS=":"; OFS="@@"} /^root/{print $1,$2,$3,$4}' /etc/passwd

#自定义输出记录分隔符
awk 'BEGIN{FS=":"; ORS="++"} {print $0}' /etc/passwd

12.多条件搜索

awk -F: '/^root|bash$/' /etc/passwd

13.输出使用量小于500M的文件系统、可用量和其所挂载点

df | awk '$4 < 512000 {print $1,$(NF-2),$NF}'

14.printf函数的格式化输出

awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
  • %s表示以字符串格式显示;-表示左对齐;20表示显示宽度
  • %d表示以十进制整数格式显示;10表示显示宽度;不加-号默认为右对齐
  • \n表示换行

15.格式化显示系统中的用户和其UID

awk -F: '{printf "Username: %-15s UID:%d\n",$1,$3}' /etc/passwd

16.非精确匹配

awk '$n ~ /pattern/ {action}' FILENAME
awk '$n ~ /(pattern1 | pattern2)/ {action}' FILENAME

17.精确匹配

awk '$n==“str” {action}' FILENAME

18.不匹配

awk '$n !~ /pattern/ {action}' FILENAME
awk '$n != “str” {action}' FILENAME

19.打印出/etc/passwd 第一个域,并且在第一个域所有的内容前面加上“用户帐号:

 cat /etc/passwd |awk -F: '{print"用户帐号:"$1}'

20.匹配/etc/passwd 第三域大于100的显示出完整信息

awk -F: '{if($3>100) print$0}' /etc/passwd

21.匹配/etc/passwd行号小于15的,并且最后一域匹配bash的信息

awk -F : '{if(NR<15 && $NF~/bash/) print $0}' /etc/passwd

22.匹配/etc/passwd第一域匹配daemon的信息

 awk -F: '$1=="daemon"' /etc/passwd

23.打印出/etc/passwd文件中的第三域数字之和

awk -F: '{sum=sum+$3}END{print sum}' /etc/passwd

24.匹配passwd文件最后一段域bash结尾的信息,有多少条

awk -F: '($NF~/bash/){print NR}' /etc/passwd |wc -l
awk -F: '{if($NF~/bash/) print $0}' /etc/passwd | wc -l
awk -F: '/bash$/{array[$7]++} END{for (i in array) print i,array[i]}' /etc/passwd
awk -F: '$NF~/bash/ {array[$7]++} END{for (i in array) print i,array[i]}' /etc/passwd

25.同时匹配passwd文件中,带mail和bash的关键字的信息

awk -F: '/root|mail/' /etc/passwd
awk -F: '$0~/root|mail/'  /etc/passwd
awk -F: '{if($0~/mail/ || $0~/root/) print $0}' /etc/passwd

26.统计访问本服务器网站的IP地址及次数

awk '{print $1}' /var/log/httpd/access_log | sort -n | uniq -c | sort -nrk 1
awk '{array[$1]++}END{for (i in array) print i,array[i]}' /var/log/httpd/access_log | sort -nrk 2

27.统计/etc/fstab 文件中每个文件系统类型出现的次数

awk '$1!~/#/ && $0!~/^$/ {array[$3]++}END{for (i in array) print i,array[i] }' /etc/fstab

28.统计文件中每个域字段的内容以及出现的次数

awk '{for (i=1;i<=NF;i++) array[$i]++}END{for (j in array) print j,array[j]}' FILENAME

29.统计/etc/fstab 文件中每个单词出现的次数

awk -F [/\ [:punct:]]+ '{for (i=1;i<NF;i++){if ($i!~/[0-9]+/ && $i!=""){array[$i]++}}}END{for (j in array) print j,array[j]}' /etc/fstab

30.提取字符串"Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"中的所有数字

echo "Yd$C@M05MB%9&B9dh7dq+YVi9xp3vp7w"|awk -F "[^0-9]+" '{for (i=1;i<=NF;i++){if ($i!="") {print $i}}}'
echo "Yd$C@M05MB%9&B9dh7dq+YVi9xp3vp7w"|awk -F "[^[:digit:]]" '{for (i=1;i<=NF;i++){if ($i!="") {print $i}}}'

31.统计netstat -tan 中各状态的次数

netstat -tan|awk '/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}'

32.统计出/etc/passwd文件中shell的种类和个数

awk -F: '{shell[$NF]++}END{for (i in shell){print i,shell[i]}}' /etc/passwd

33.计算/etc/passwd中所有用户的UID平均数,以及GID平均数

awk -F: '{U+=$3;G+=$4}END{print "U_avg:"U/NR"\nG_avg:"G/NR}' /etc/passwd

34.使用:符号做分隔符,将字段逆序输出/etc/passwd文件的每行

awk -F: '{for(i=NF;i>1;i--)printf "%s:",$i;print $i}' /etc/passwd

35.统计当前目录下的文件占用的总字节数

ls -l | awk 'BEGIN {SIZE=0;}{SIZE=SIZE+$5} END{print "size is",SIZE}'

36.统计ps中VSZ,RSS各自总和

 ps aux | awk 'BEGIN{print "ps MEM statistic"}{V+=$5;R+=$6}END{print "VSZ_SUM: "V/1024"M\n""RSS_SUM:"R/1024"M"}'

37.根据uid值给用户分等级 Admin system users输出格式:
LEVEL NAME
Admin root
sysuser bin
users seke

[root@eddy ~]# cat level.awk 
BEGIN{
	print "LEVEL\t\tNAME"
}
{if($3==0){
	a++;print"admin\t\t"$1"\n"
	}
else if($3<500){
	s++;print "sysuser\t\t"$1"\n"
	}
else{
	u++;print "user\t\t"$1"\n"
	}
}
 END{
	print "admin:"a,"sysuser:"s,"user:"u
}
[root@eddy ~]# awk -F : -f level.awk /etc/passwd

38.统计/etc/passwd的账户人数

awk 'BENGIN {count=0;}{count+=1} END{print "user count is ", count}' /etc/passwd

39.打印九九乘法表 (取1-9使用 seq 9)

seq 9 | sed 'H;g'| awk -v RS='' '{for(i=1;i<=NF;i++) printf("%d*%d=%d%s",i,NR,i*NR,i==NF?"\n":"\t")}'
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值