sed命令:
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
sed使用参数
[root@www ~]# sed [-nefr] [动作]
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。
但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
s/regexp/replacement/:替换由regexp所匹配到的内容为replacement
w /path/to/somefile:把指定的内容另存至/path/to/somefile路径所指定的文件中
r /path/from/somefile:在文件的指定位置插入另一个文件的所有内容,完成文件合并    
function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法

1. 定址:定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。

#:指定行

$:最后一行

/regexp/:任何能够被regexp所匹配的到的行

\%regexp%:同上,只是换作%为regexp的边界符

/regexp/|:匹配时忽略字符大小写

\%regexp%|:匹配时忽略字符大小写

startline,endline

#,/regexp/:从#行开始,到第一次被/regexp/所匹配到的行结束,中间所有的行

/regexp/,/regexp2/:从第一次被/regexp/所匹配到的行,到被/regexp2/所匹配的行结束,中间所有的行

#,+n:从#行开始,再向下的n行

#,$:从#开始到最后一行

first~step:指定起始行,以及步长

2.d,删除行

例1.[root@lys ~]# sed '2d' /etc/fstab

wKioL1X5JPeiHOgWAAEZzjGjZwI419.jpg

例2.删除/etc/fstab第五行后所有的行,$代表末行

[root@lys ~]# sed '5,$d' /etc/fstab

wKiom1X5IsDg_4vwAAA6u7UvvhY376.jpg

3.p命令:命令p用于显示模式空间的内容。默认情况下,sed把输入行打印在屏幕上,选项-n用于取消默认的打印操作。当选项-n和命令p同时出现时,sed可打印选定的内容。

例3.

[root@lys ~]# sed  -n '/UUID/p' /etc/fstab

wKiom1X5JUCjH6VIAAC4E6oq2Vw765.jpg

4.s命令:格式:sed 's/要替换的字符串/新的字符串/g'   (要替换的字符串可以用正则表达式)

例4.1将/etc/fstab中的UUID 替换成AAID

wKiom1X5IsHjQ7fPAAEgYwS1z3M117.jpg

例4.2删除/etc/selinux/config文件中所有以#开头,后跟至少一个空白字符的行的行首的#和空白字符

wKioL1X5JPfxZxZJAAEL3JdK7-s527.jpg

5.first~step:指定起始行,以及步长。w命令是读入一个文件内容

例5.1将/etc/passwd文件的奇数行保存到/tmp/passwd中,其中sed 1~2表示从第一行开始,以2行为一个跨度进行匹配

wKioL1X5JPfDtwnyAAKAV1qmGdE356.jpg

wKiom1X5IsHAnwpfAAFPrhHiLQw641.jpg

6.e选项:-e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。

例6.先匹配“root”的行,然后将“root”替换成“adm”

wKioL1X5JPfAIlt6AAEAmdQ0nc4630.jpg

7.i\命令:i\ 命令是在当前行的前面插入新的文本。

例7.在/etc/passwd的第四行前插入test

wKiom1X5IsGBND98AACvjRGGYgE101.jpg

8.r命令:r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。

wKiom1X5IsGiIYIzAAFQDelvwzc614.jpg

9.sed的一些特殊命令如下:

高级命令:

h:用模式空间中的内容覆盖保持空间的内容;

H:把模式空间中的内容追加至保持空间中内容的后面;

g:从保持空间中取到其内容,并将其覆盖模式空间中的内容;

G:从保持空间中取到其内容,并将其追加在模式空间中的内容的后面;

x:把保持空间和模式空间中的进行交换;

n:读取匹配到的行的下一行至模式空间;(会覆盖模式空间中的原有内容);

N:读取匹配到的行的下一行至模式空间,追加在模式空间中原有内容的后面;

d:删除模式空间中的内容;

D:删除多行模式空间中的首行;

注意:命令功能可使用!取反;分号可用于分隔脚本;

sed 'G' /etc/issue: 在文件中的每行后方添加空白行;

sed '$!d' /etc/fstab:保留最后一行;
sed '/^$/d;G' /etc/issue: 保证指定的文件每一行后方有且只有一个空白行;
sed 'n;d' /etc/issue:保留奇数行;
sed -n '1!G;h;$p' /etc/issue
sed '$!N;$!D' /etc/issue

 

awk命令详解


什么是awk?awk是三个人名的缩写,他们是:Aho、(Peter)Weinberg和(Brain)Kernighan。awk是一个优秀的样式扫描与处理工具。awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。awk 命令可以在命令行输入,也可以写在awk 脚本文件里。要处理的文本行则来自文件、管道或标准输入。

1.基本语法

awk [options] 'program' file file ...

awk [options] 'PATTERN{action}' file file ...

2.从文本输入

2.1下面演示/etc/passwd的文件,用awk打印出含有root的行

wKiom1X5PlHDL6oeAAA_D9YvxAU886.jpg

2.2当打印文件/etc/passwd的某一行含有模式root时,打印改行的1.3两个字段

wKioL1X5QaWCpHjkAAApE6fgsOA291.jpg

3.从命令输入

可以将一条或多条linux命令的输出通过管道发给awk处理。格式如下:

wKioL1X5Qkuz3ASqAAAsT2u3TDw650.jpg

4.awk的变量:内置变量和自定义变量

4.1内置变量

  • FS:Field Seperator, 输入时的字段分隔符

  • RS:Record Seperator, 输入行分隔符

  • OFS: Output Field Seperator, 输出时的字段分隔符

  • ORS: Outpput Row Seperator, 输出时的行分隔符

  • NF:Numbers of Field,字段数

  • NR:Numbers of Record, 行数;所有文件的一并计数

  • FNR:行数;各文件分别计数

  • ARGV:数组,保存命令本身这个字符

  • ARGC: 保存awk命令中参数的个数

  • FILENAME: awk正在处理的当前文件的名称

4.2可自定义变量

  • -v var_name=VALUE

  • 可以program中定义变量;

  • 可以命令行中通过-v选项自定义变量;

  • 变量名区分字符大小写;

5.print函数

也可以用{print}形式在awk命令的动作部分显式地调用print函数。print函数的参数可以是变量、数值或字符串常量。字符串必须用双引号括起来。参数之间用逗号分隔,如果没有逗号,所有的参数就会被串在一起。默认情况下是空格逗号等价于OFS中的值.

例.利用date命令输出时间,通过awk截取年份和月份

wKioL1X5R-Kw_dIIAAAt6tg1HXA999.jpg


wKioL1X5SEqh6_rbAAEw-8tW13o184.jpg

6.printf函数

printf函数返回一个带格式的字符串给标准输出,如同C语言中的printf语句一样。printf语句包括一个加引号的控制串,控制串中可能嵌有若干格式说明和修饰符。控制串后面跟一个逗号,之后是一列由逗号分隔的表达式。printf函数根据控制串中的说明编排这些表达式的格式。与print函数不同的是, printf不会在行尾自动换行。因此,如果要换行,就必须在控制串中提供转义字符\n。

wKiom1X5R9bgoNWZAAK-uTa7aPs189.jpg

下面通过一个实例来看

wKiom1X5SIPieG1EAAA3vcPzOMc910.jpg

对于echo命令的输出,Linux是经管道发给awk。printf函数包含一个控制串。百分号让printf做好准备,它要打印一个占15个格、向左对齐的字符串,这个字符串夹在两个竖杠之间,并且以换行符结尾。百分号后的短划线表示左对齐。

7.字段分隔符

输入字段分隔符awk的内存变量FS中保存了输入字段分隔符的值。使用FS的默认值时,awk用空格或制表符来分隔字段,并且删除各字段前多余的空格或制表符。

wKioL1X5VpvDCN5-AAA3Xj_XZbc551.jpg

虽然前面-F有指定分隔符:,但是后面通过赋值给变量OFS将其覆盖了。也就是说我们可以通过OFS这个变量来定义分隔符。

8.awk关系运算符

下表列出了所有关系运算符。关系表达式的计算结果为真时,表达式的值为1;反之,则为0。

运算符          含义           

<             小于

<=            小于等于

==            等于

!=            不等于

>=            大于等于

>             大于

~             与正则表达式匹配

!~            与正则表达式不匹配

9.算术运算

运算符              含义         

+                 加

-                 减

*                 乘

/                 除

%                 模

^                 幂

10.逻辑运算

运算符              含义

&&                 与

||                 或

!                 非

11.awk的BEGIN与END模式

BEGIN模式后面跟了一个操作块。awk命令必须在对输入文件进行任何处理之前先执行该操作块。实际上,不需要任何输入文件,也能对BEGIN块进行测试,因为awk要在执行完BEGIN操作块后才开始读取输入。BEGIN操作常常被用于修改  内存变量(OFS、RS、FS等)的值、为 用户自定义变量赋初值和打印输出的页眉或标题。

wKiom1X5W47yHCxRAACy7va08aE122.jpg

说明在处理输入文件之前,awk先把(FS)设为冒号,把输出分隔符(OFS)设为制表符,还把输出记录分隔符(ORS)设为两个换行符。如果BEGIN的操作块中有两条或两条以上语句,必须用分号分隔它们或每行只写一条语句(在shell的命令提示符下输入时,必须用反斜杠来转义换行符)。


[root@lys ~]# awk 'BEGIN{print "MAKE YEAR"}'

MAKE YEAR

awk将显示MAKE YEAR。awk打开输入文件之前先执行该print函数,即使没有指定输入文件,awk也照样打印MAKE和YEAR。

END模式不匹配任何输入行,而是执行任联何与之关的操作。awk处理完所有输入行之后才处理END模式。

例:

[root@lys ~]# awk 'END{print "The number of record is " NR}' /etc/fstab 

The number of record is 13

awk处理完整个文件后才开始执行END块。此时NR的值是最后这条记录的记录号

[root@lys ~]# awk '/UUID/{count++}END{print "UUID was found " count " times."}'  /etc/fstab 

UUID was found 5 times.

每遇到一个包含模式Mary的行,用户自定义的变量counter的值就加1.

12.输出重定向

[root@lys ~]# awk '$4 >= 70 {print $1,$2 > "passing_file"}' /etc/ssh/

如果记录的第4个字段的值大于或等于70,它的头两个字段就被打印到文件passing_ file 中。

13.awk if 语句

[root@lys ~]#  awk '{if($6 > 50) print $1 "Too high"}' /etc/grub2.cfg 

#Too high

#Too high

#Too high

ifToo high

ifToo high

ifToo high

ifToo high

ifToo high

ifToo high

#Too high

menuentryToo high

ifToo high

linux16Too high

menuentryToo high

ifToo high

linux16Too high

#Too high

#Too high

#Too high

ifToo high

在if操作块中对表达式进行测试。如果第6个字段的值大于50,就执行打印语句。

14.if else 语句


[root@lys ~]# awk '{if($6 > 50) {count++;print $3;} else {x+5;print $2;}}' /etc/grub2.cfg 

NOT

is

/etc/grub.d

BEGIN

pager=1

-s

如果第一个表达式为真,即第6个字段($6)的值大于50,则执行表达式后面的这个语句块。否则就执行else后面的那个语句块。注意,语句块必须括在花括号中。

15.awk循环

[root@lys ~]# awk '{i=1; while(i<=NF){print NF,$i; i++ }}' /etc/passwd

1 root:x:0:0:root:/root:/bin/bash

1 bin:x:1:1:bin:/bin:/sbin/nologin

1 daemon:x:2:2:daemon:/sbin:/sbin/nologin

1 adm:x:3:4:adm:/var/adm:/sbin/nologin

1 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

1 sync:x:5:0:sync:/sbin:/bin/sync

1 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

1 halt:x:7:0:halt:/sbin:/sbin/halt

1 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

1 operator:x:11:0:operator:/root:/sbin/nologin

1 games:x:12:100:games:/usr/games:/sbin/nologin

2 ftp:x:14:50:FTP

以上只是部分输出,变量i被初始化为1 ;当i小于或等于记录的字段数(NF)时,先执行print语句,然后将i加1。接下来又重新测试表达式,直至i大于NF的值。变量i要在awk开始处理下一条记录时被重置。

16.for循环

[root@lys ~]#  awk '{for(i=1;i<=NF;i++) print NF,$i}' /etc/passwd

1 root:x:0:0:root:/root:/bin/bash

1 bin:x:1:1:bin:/bin:/sbin/nologin

1 daemon:x:2:2:daemon:/sbin:/sbin/nologin

1 adm:x:3:4:adm:/var/adm:/sbin/nologin

1 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

1 sync:x:5:0:sync:/sbin:/bin/sync

1 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

1 halt:x:7:0:halt:/sbin:/sbin/halt

1 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

1 operator:x:11:0:operator:/root:/sbin/nologin

1 games:x:12:100:games:/usr/games:/sbin/nologin

变量i被初始化为1 ;当i小于或等于记录的字段数(NF)时,先执行print语句,然后将i加1。接下来又重新测试表达式,直至i大于NF的值。变量i要在awk开始处理下一条记录时被重置。

17.next:提前结束对本行的处理进而提前进入下一行的处理

[root@lys ~]#   awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd

bin 1

adm 3

sync 5

halt 7

operator 11

nobody 99

dbus 81

abrt 173

polkitd 999

tss 59

postfix 89

chrony 997

以上语句意义是如果第三个字段的值是偶数,则跳过,并打印1,3字段
18.awk数组:数组在awk中被称为关联数组(associative arrays) ,因为它的下标既可以是数字也可以是字符串。下标通常又被称作键(key),并且与对应的数组元素的值相关联。数组元素的键和值都存储在awk程序内部的一个表中,该表采用的是散列算法。

[root@lys ~]# awk -F : '{id[NR]=$3}END{for(x=1; x<=NR; x++){print id[x]}}' /etc/passwd

0

1

2

3

4

5

6

7

awk变量NR保存当前记录的记录号。本例用NR作为下标,把每条记录的第3个字段赋值给数组中的相应元素。最后,for循环对数组进行循环处理,打印出保存在数组中的值

19.split与delete函数 awk的内置函数split能够将字符串拆分为词,然后保存在数组中。您可以指定字段分隔符,也可以就用FS的当前值

格式:

split (字符串,数组,字段分隔符)

split (字符串,数组)

[root@lys ~]# netstat -tn | awk '/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip[i]}'

192.168.2.107 3

delete函数用于删除数组元素

awk '{line[x++]=$2}END{for(x in line) delete(line[x])}' /etc/passwd

赋给数组line的值是第2个字段的值。所存记录都处理完后,特殊for循环将遍历数组的所有元素,并由delete函数来删除它们。