Shell-05Shell三剑客之sed

sed 特点

sed是一个脚本型的编辑器,是非交互式的编辑器,也就是说sed与常见的编辑器不同(比如说vim),sed没有交互式的编辑界面以及光标移动或者庞大的快捷键/功能,sed 的使用就是很简单的一个脚本行。

sed 作为编辑器有如下特点让人难以拒绝:

(1) 非交互,基于模式匹配的过滤及修改文本

(2) 逐行处理,所以那些对舒适的交互式编辑而言太大的文件使用sed 会显得格外有优势

(3) 可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种编辑操作

(4) 脚本化,在shell 脚本编程中你总不能打开vim 吧?

模式空间

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

sed命令的格式

#sed [options] 'AddressCommand' file ...
sed 选项 '动作' 文件名
前置命令(eg.cat 文件名) | sed 选项 '动作'
选项:
    -n :静默模式,不再默认显示模式空间中的内容只显示被修改的行的内容
    -e SCRIPT -e SCRIPT:可以同时执行多个脚本
    -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
    -r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
    -i :直接修改读取的文件内容,而不是输出到终端。


#注意
	命令需要用单引号或者双引号引起来号;
	当你的命令中字符需要用到单引号时,是无法通过 '\' 来转义的,此时使用命令用双引号引起来即可。
	用到正则时需要用 '/' 进行标记

动作的格式

[address1[,address2]]动作/pattern/replacement/[flags]

  • sed在匹配前可以指定针对哪些行,这些行的指定你可以直接使用数字,也可以通过匹配得到,address 就是来指定行范围;
  • pattern 模式匹配,也就是核心的正则表达式;后面业务中发现大部分时间都是在这里纠结。
  • replacement是被替换的内容,如何为空就是删除的意思
  • flags 替换时的功能选项
  • 不仅仅可以使用///还可以使用’@@@'进行分割

address 控制范围的行寻址

首先说明[address1[,address2]]可以不存在

#sed -n '3p' xxx.txt
3p 打印第三行,p 功能为打印
-n 表示静默模式,一般sed都有把所有读到的行打印出来,如果不加这个参数,它将一行行打印读到的,并且由于 3p 会重复打印第三行;

#打印最后一行
sed -n '$p' xxx.txt

# 打印从N行开始到最后一行
 sed -n 'N,$p' xxx.txt
 
#使用 + 操作符来间接寻址,表示从某行开始向下多少行
sed -n 'N,+2p' xxx.txt

#使用 ~ 指定地址范围,它使用N~M 的形式,它告诉SED应该处理N行开始的每M行
sed -n 'N~M p' xxx.txt

#使用正则表达式匹配指定的行,注意必须用正斜杠将正则表达式封起来 
 sed -n '/正则表达式/p' xxx.txt

#上面可以结合使用
sed -n '/正则表达式/,N~M p' xxx.txt

#两个正则匹配
sed -n '/正则表达式1/,/正则表达式2/p' xxx.txt

pattern 模式匹配

  • ^ 表示一行的开头。如:/^#/ 以#开头的匹配。
  • $ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
  • \< 表示词首。 如:\ 表示以 abc 为首的詞。
  • \> 表示词尾。 如:abc\> 表示以 abc 結尾的詞。
  • . 表示任何单个字符。
  • * 表示某个字符出现了0次或多次。
  • [ ] 字符集合。 如:[abc] 表示匹配a或b或c,还有 [a-zA-Z] 表示匹配所有的26个字符。如果其中有^表示反,如 [^a] 表示非a的字符

动作种类

a :在指定行后 新增一行或多行内容
c :替换指定行的内容
d :删除指定行的内容
i :在指定行之前 插入一行或多行内容
s :替换指定内容
n : 获取下一行命令
p : 显示符合条件的行;
r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中; 
暂存和取用的命令:H h G g

flag种类

命令格式的 flag 部分,后面出现 /g 表示改行出现的所有匹配内容都进行替换。如果不指定 flag 将默认只对改行匹配到的第一个做更改。

除此之外还提供了其它几个命令

  • 数字n,表示只更改该行匹配到的第n个
  • p 只输出匹配到的行,再行寻址里面已经用过
  • w 存储改变的行到文件,比如sed -n 's/i/I/w junk.txt' books.txt
  • i 匹配时忽略大小写

sed 的简单使用

$ echo "hello,world" | sed "s/hello/hi/"
hi,world

$ echo "hello,world" > file
$ sed 's/hello/hi/' file
hi,world

删除行内容

1、删除行内容删除第2行的内容

cat file.txt | sed '2d'

sed '2d' file.txt

2、删除第2-5行的内容

cat file.txt | sed '2,5d'

sed '2,5d' file.txt

3、删除第2行到最后一行的内容

cat file.txt | sed '2,$d'

sed '2,$d' file.txt

新增、插入行内容

1、在第2行后新增内容

  • cat file.txt | sed ‘2a hello world’

2、在第2行前插入内容

  • cat file.txt | sed '2i hello world

3、在第2行后新增2行内容

  • cat file.txt | sed ‘2a hello**\n**world’

替换行内容

1、把第2行的内容替换为 hello world

  • cat file.txt | sed ‘2c hello world’

2、把第2-5行的内容替换为 hello world

  • cat file.txt | sed ‘2,5c hello world’

3、只显示被修改的行的内容

  • cat file.txt | sed -n ‘2c hello world’

搜索指定内容

1、搜索含有abc的行

  • cat file.txt | sed -n ‘/abc/p’

2、搜索并删除指定内容

  • cat file.txt | sed ‘/abc/d’

替换指定内容

1、默认只替换每行中模式首次匹配的内容

  • cat file.txt | sed ‘s/abc/‘替换后的内容’/’

2、g标记可以使sed执行全局替换

  • cat file.txt | sed ‘s/abc/‘替换后的内容’/g’

3、g标记可以使sed替换第N次出现的匹配

  • sed ‘s/abc/xxx/2g’ file.txt

直接操作文件内容(危险动作)

1、直接删除文件内容

sed -i '2,5d' file

2、直接替换文件内容

sed -i 's/abc/xxx/g' file

在sed中使用正则表达式

1、搜索并删除空行

sed '/^$/d' file.txt

2、替换3位数的数字

[root@linuxprobe test_shell]# cat b.txt
a 1 b 22 c 333 d 4444
[root@linuxprobe test_shell]# sed 's/\b[0-9]\{3\}\b/666/g' b.txt
a 1 b 22 c 666 d 4444

[root@linuxprobe test_shell]# cat file
a1
b22
c333
d4444
ab12abc123abcd1234
[root@linuxprobe test_shell]# sed 's/[0-9]\{3\}/666/g' file
a1
b22
c666
d6664
ab12abc666abcd6664

3、操作文件内容时,备份原文件

[root@linuxprobe test_shell]# cat file
xxx 123 xxx123 123xxx
[root@linuxprobe test_shell]# sed -i.bak 's/abc/xxx/g' file
[root@linuxprobe test_shell]# cat file
xxx 123 xxx123 123xxx
[root@linuxprobe test_shell]# ls
b.txt  file  file.bak  test.sh
[root@linuxprobe test_shell]# cat file.bak
xxx 123 xxx123 123xxx

4、已匹配字符串标记( & )

在 sed 中 & 指代模式所匹配到的字符串

[root@linuxprobe test_shell]# cat file
abc 123 abc123 123abc
[root@linuxprobe test_shell]# sed 's/abc/[&]/g' file
[abc] 123 [abc]123 123[abc]

5、子串匹配标记( \1 \2 \3 …)

在sed中 \1 \2 \3 指代出现在括号中的部分正则表达式所匹配到的内容

[root@linuxprobe test_shell]# echo abc 123 | sed 's/abc \([0-9]\)/\1/'
123

对于匹配到的第一个子串,其对应的标记是 \1 ,匹配到的第二个子串是 \2 ,往后以此类推。

[root@linuxprobe test_shell]# echo HELLO world | sed 's/\([A-Z]\+\) \([a-z]\+\)/\2 \1/'
world HELLO

6、组合多个表达式

[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/' | sed 's/[0-9]\+/666/'
xxx 666
[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/;s/[0-9]\+/666/'
xxx 666
[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/;s/[0-9]\+/666/'
xxx 666

7、引用变量

[root@linuxprobe test_shell]# echo user | sed "s/user/$USER/"
root

备注:在双引号中,可以引用变量。

8.删除配置文件中注释行

#号
sed -ri '/^[ \t]*#/d' u.txt
//号
sed -ri '#^[ \t]*//#d' u.txt
无内容行
sed -ri '/^[ \t]*$/d' u.txt


sed -ri '/^[ \t]*($|#)/d' u.txt  合并

9、删除/etc/grub.conf文件中行首的空白符

sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf 
sed 's/^\ \+//' /etc/grub.conf

10、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5

sed 's@id:id:[0-9]:initdefault::initdefault:@\15\2@g' /etc/inittab
sed -r 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab

11、删除/etc/inittab文件中的空白行;

sed '/^$/d' /etc/inittab

12、删除/etc/inittab文件中开头的#号;

sed 's@^#@@g' /etc/inittab

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

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

14、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#

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

15、取出一个文件路径的目录名称;

echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g'     
取出基名:
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g'     

你可能感兴趣的:(#,Liunx,linux,sed,运维)