Shell正则三剑客 | sed命令

sed简介

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,sed只是对缓冲区中原始文件的副本进行编辑,并不是编辑原始的文件。除非你使用重定向存储输出或者使用使用sed编辑命令中的w选项。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作。

 

sed命令参数

  • a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
  • c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
  • d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
  • i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
  • p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
  • s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦

 

元字符集

^:              匹配一行的开始

$:              匹配一行的结束

.:               匹配某个字符

[abc]:        匹配指定范围字符

 

sed命令基本用法

sed : Stream EDitor 行编辑器 (全屏编辑器 : vi)

sed : 模式空间 默认不编辑原文件,仅对模式空间中的数据做处理 : 而后,处理结束后,将模式空间打印至屏幕: sed 'AddressCommand' file ...

Address(地址) 指定方法: 1、StartLin(起始行),EndLine(结束行) 比如 :1,100 $ :最后一行 2、/RegExp/(正则表达式指定的模式) /^root/ 3、/pattern1/,/pattern2/ 第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行 4、LineNumber 5、StartLine(起始行), +N 从StartLine开始,向后的N行:

命令格式

sed [options] '{command}' [filename]
sed [options] -f scriptfile [filename]

选项

常用选项选项说明
sed -n抑制自动输出;静默模式,不再默认显示模式空间中的内容
sed -e SCRIPT -e SCRIPT添加脚本 ;可以同时执行多个脚本
sed -f /PATH/TO/SED_SCRIPT添加脚本文件
           sed -f /PATH/TO/SED_SCRIPT file

| sed -i | 编辑文件内容;直接修改源文件 | | sed -i.bak | 修改文件同时创建.bak备份文件 | | sed -r | 使用扩展的正则表达式;将指定的文件的内容添加至符合条件的行处 |

常用命令参数参数说明
a \“string”在匹配后面添加新的行,内容为“string”
  案例:1、sed '/^\//a \# hello word' /etc/fstab    #在/etc/fstab后面,添加hello word。
  2、sed '/^\//a \# hello word\n#hello,linux' /etc/fstab         #在/etc/fstab后面,添加hello word和hello,Linux。

| d | 删除符合条件的行 | 案例 :1、sed '1,2d' /etc/fstab #删除/etc/fstab 中的第1,2行 2、sed '1,$-1d' /etc/fstab #删除/etc/fstab 中的第1到到数第二行 3、sed '3,$d' /etc/fstab #删除/etc/fstab 中的31到最后1行 | i \string | 在匹配前面添加新行,内容为string | \n:可以用于换行 | s | 查找替换,默认只替换每行中第一行被模式匹配到的字符 | 加修饰符 g:全局替换 i:忽略字符大小写 案例 :1、 sed 's/oot/OOT' /etc/fstab #在/etc/fstab中的oot替换成OOT 2、 sed 's/^//#/' /etc/fstab #在/etc/fstab中的行首的/替换成# 3、 sed 's///#/' /etc/fstab #在/etc/fstab中的全部的/替换成# | p | 打印 / 显示符合条件的行|    案例 : sed '/^//p' /etc/fstab #显示/etc/fstab下,以/开头的行 | y FILE| 转换 |

| w FILE| 将地址指定范围内的行另存至指定的文件中 | | h H | 拷贝/添加模式空间到存放空间 | | g G | 拷贝/添加存放空间到模式空间 |

sed -i.bak '/^\s*#/d;/^$/d' <filename>

详细介绍一下上面的脚本:

  • sed -i.bak:sed 命令会创建一个以.bak结尾的备份文件,用来备份原始的文件。
  • /^:表示行首。
  • \s*:匹配任何不可见字符,包括空格、制表符、换页符等。
  • #/:shell 脚本中的注释标记。/^\s*#/一起使用用来查找注释行和带有不可见字符的注释行。
  • d:用来删除匹配的行。
  • ;/^$/d;是表达式的分隔符,后面的表达式跟前面的表达式意思很像,用来删除空白行, "$"匹配输入字符串的结束位置。

 

指令参数

a\    当前行下面插入文本。
i\    在当前行上面插入文本。
c\    把选定的行改为新的文本。

d    删除,删除选择的行。
D    删除模板块的第一行。
s    替换指定字符
h    拷贝模板块的内容到内存中的缓冲区。
H    追加模板块的内容到内存中的缓冲区。
g    获得内存缓冲区的内容,并替代当前模板块中的文本。
G    获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l    列表不能打印字符的清单。
n    读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N    追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
  1. N             追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。

  2. p             打印模板块的行。

  3. P             (大写) 打印模板块的第一行

  4. ^             行的开始

  5. $             行的结尾

  6. .             一个字符

  7. *             0个或多个前一个字符

  8. []            方括号中的所有字符

  9. {}             重复次数

  10. ()             组

  11. /./            匹配至少有一个字符的行

  12. /../           匹配至少有两个字符的行

  13. /^#/           匹配用#开头的行

  14. /^$/           匹配空行

  15. /}$/           匹配用}结尾的行(没有空格在后面)

  16. /} *$/         匹配用}结尾的行(可以有空格在后面)

  17. /[abc]/        匹配小写的a或b或c

  18. /^<a href="#footnote-abc"><sup>[abc]</sup></a>/                匹配开头不是小写的a或b或c

sed命令小练习

打印操作:p命令

1. sed -n '5'p /etc/passwd

2. sed -n '1,5'p /etc/passwd

3. sed -n '1,$'p /etc/passwd

4. sed -n '/root/'p /etc/passwd

5. sed -n '/^1/'p /etc/passwd

6. sed -n 'in$'p /etc/passwd

7. sed -n '/r..o/'p /etc/passwd

8. sed -n 'oo*'p /etc/passwd

9. sed -e '1'p -e /111/'p -n /etc/passwd

10、sed -n '+5'p /etc/passwd

 

11、sed '2r /etc/issue' /etc/fstab                          #在/etc/fstab第二行添加etc/issue

12、sed '$r /etc/issue' /etc/fstab                          #在/etc/fstab第后面行添加etc/issue

13、sed '1,2r /etc/issue' /etc/fstab                     #在/etc/fstab第一,二行添加etc/issue

sed -n '1,3p'                                             #打印出file1文件第一到第三行

sed -e 's/jk$/yz/g' test.txt                                           #修改文本中以jk结尾的替换成

14、删除/etc/grub.conf文件中行首的空白符                 sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf

15、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;              sed 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab

16、删除/etc/inittab文件中空白行;                            sed '/^$/d' /etc/inittab

17、删除/etc/inittab文件中开头的#号                         sed 's@^@@g' /etc/inittab

18、删除某文件中以后面的空白字符,但要求#号后面必须有空白字符;                     

sed -r 'S@^[[!space:]]+#@@g' /etc/inittab

19、删除某文件中以空白字符后面跟#类的行中的开头的空白字符                                 # sed -r 's@^[[!space:]]+#@@g' /etc/inittab

20、取出一个文件路径的目录名称; echo "/etc/rc.d/" sed -r 's@^(/.*/)[^/]+/7@\1@g'

21、传递一个参数(单字符就行)给脚本,如参数为q,Q,quit,或Quit,就退出脚本否则,就显示用户的参数:

#!/bin/bash

if [ $1 = 'q' ];then echo "Quiting..."

   elif [ $1 = 'Q' ];

      then echo "Quiting..." exit 2 elif [ $1 = 'quit' ];

       then echo "Quiting..." exit 4 else echo $1

fi

 

22、统计一共有多少个用户

for I in 'seq 1 $LINES'; do echo "Hello, 'head -n $I /etc/passwd | tail -l | cut -d:-f1'";done 只向默认shell为bash的用户问声好

23、添加10个用户user1到user10,密码同用户名,但要求只有用户不存在的情况下才能添加。 扩展 : 接受一个参数: add : 添加用户user1..user10 del :删除用户user1..user10 其他:退出

#!/bin/bash

for I in (1..10); do if id user$I &>/dev/null; then echo 'user$I' exists. else useradd user$I echo user$I | passwd --stdin user$I &> /dev/null echo "Add user user$I finished." fi done

#!/bin/bash

for I in (1..10); do if id user$I &>/dev/null; then userdell -r user$I echo 'Delete user$I' fineshed. else echo "user$I not exist." fi done

24、查找/var目录下属主为root并且属组为mail的所有文件:

find /var -user root -group mial

 

25、查找/usr目录下不属于root,bin,或student的文件: find /usr -not -user root -a -not -user bin -a -not -user student find /usr -not ( -user root -o -user bin -o -user student )

26、查找/etc目录下最近一周内内容修改且不属于root及student用户的文件: find /etc -mtime -7 -not \ ( -user root -o -user student ) find /etc/ -mtime -7 -not -user root -a -not -user student

 

27、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改为root: find / \( -nouser -o nogroup \) -a -atime -1 -exec chown root:root () ;

28、查找/etc目录下大于1M的文件,并将其文件写入/tmp/etc.largefiles文件中:                 find /etc/ -size -1M >> /tmp/etc.largefiles

 

29、查找/etc目录下所有用户都没有写权限的文件,显示出其详细信息;                                 find /etc -not -perm /222 -ls

30、查找/etc目录下大于1M的文件,并追加到/tmp/etc.largefiels

find /etc -szie +1M -exec echo {} >> /tmp/etc.largefile ; find /etc -szie +1M xarges echo {} >> /tmp/etc.largefile

 

31、命令:a\

在匹配行的后面加入一行文本

示例(4)匹配100的行,后面加入一行"new line"

sed '/100/'a\ "new line" hello.txt

输出内容为:

1 2 3

10 20 30

100 200 300

new line

命令:i\

在匹配行的前面加入一行文本

示例(5)匹配100的行,前面加入一行"new line"

sed '/100/'i\ "new line" hello.txt

输出内容为:

1 2 3

10 20 30

new line

100 200 300

 

命令:c\

将匹配行替换为目的行

示例(5)匹配100的行,替换为"new line"

sed '/100/'c\ "new line" hello.txt

输出内容为:

1 2 3

10 20 30

new line

 

命令:d

将匹配行删除

示例(5)删除匹配100的行

sed '/100/'d hello.txt

输出内容为:

1 2 3

10 20 30

 

命令:s

将匹配行替换

详细命令为:s/pattern-to-find/replacement-pattern/g

pattern-to-find:被替换的串

replacement-pattern:替换成这个串

g:全部替换,默认只替换匹配到的第一个

示例(5)讲100替换为hello

sed 's/100/hello/g' hello.txt

输出内容为:

1 2 3

10 20 30

hello 200 300

 

匹配以10开头的行,并替换为yes,并输出

sed -n 's/^10/yes/p' hello.txt

输出内容为:

yes 20 30

yes0 200 300

 

取出文件中行手的行号与冒号

设hello.txt的内容为

1:#!/bin/sh

2:cat hello.txt

3:exit

 

sed -n -e 's/^[0-9]\{1,\}://g'p hello.txt

输出结果为:

#!/bin/sh

cat hello.txt

exit

 

32、

33、

34、

35、

36、

37、

38、

39、

40、

删除操作:d命令

  1. ## 删除 第1行

  2. sed '1'd /etc/passwd

  3. sed '1d' /etc/passwd

  4. ## 删除 第1行 和 第3行

  5. sed '1,3'd /etc/passwd

  6. ## 删除包含 字符串oot的行

  7. sed '/oot/'d /etc/passwd

  8. ## 删除空白行

  9. sed '/^$/d' /etc/passwd

  10. ## 删除文件最后一行

  11. sed '$d' /etc/passwd

12、sed '1,+2d' /etc/fstab #删除第一行和向后的两行

13、

替换文件内容

  1. sed 's/[0-9]//g' /etc/passwd

  2. sed s/[a-zA-Z]//g' /etc/passwd

  3. sed 's#ot#to#g' /etc/passwd

追加(行下追加):a\

  1. ## 行下追加

  2. [root@ansible-master awk]# head -2 text | sed '/^root/a\this is a test line'

  3. root:x:0:0:root:/root:/bin/bash

  4. this is a test line

  5. rootaaaaa:x:10:0:root:/root:/bin/bash

  6. this is a test line

  7. ## 指定行下追加

  8. [root@ansible-master awk]# head -3 text | sed '2a\this is a test line'

  9. root:x:0:0:root:/root:/bin/bash

  10. rootaaaaa:x:10:0:root:/root:/bin/bash

  11. this is a test line

追加(行下追加):a\

  1. ## 指定行上追加

  2. [root@ansible-master awk]# head -3 text | sed '2i\this is a test line'

  3. root:x:0:0:root:/root:/bin/bash

  4. this is a test line

  5. rootaaaaa:x:10:0:root:/root:/bin/bash

  6. ## 匹配行上追加

  7. [root@ansible-master awk]# head -5 text | sed '/^root/i\this is a test line'

  8. this is a test line

  9. root:x:0:0:root:/root:/bin/bash

  10. this is a test line

  11. rootaaaaa:x:10:0:root:/root:/bin/bash

互换

  1. ## 匹配并替换,将第1字段 和 第7字段进行互换

  2. [root@ansible-master awk]# sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' /etc/passwd

  3. /bin/bash:x:0:0:root:/root:root

  4. /sbin/nologin:x:1:1:bin:/bin:bin

  5. /sbin/nologin:x:2:2:daemon:/sbin:daemon

  6. /sbin/nologin:x:3:4:adm:/var/adm:adm

  7. ## 在行首添加字符串 aaa

  8. [root@ansible-master awk]# sed -r 's/(.*)/aaa:&/' /etc/passwd

  9. aaa:root:x:0:0:root:/root:/bin/bash

  10. aaa:bin:x:1:1:bin:/bin:/sbin/nologin

  11. aaa:daemon:x:2:2:daemon:/sbin:/sbin/nologin

转载于:https://my.oschina.net/u/3803405/blog/2253637

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值