linux三剑客之sed

sed(Stream Editor,流编辑器),对标准输出或文件逐行进行处理

 

语法格式

  第一种形式:stdout | sed [option] "pattern command"
  第二种形式:sed [option] "pattern command file"

 

选项(option)

选项

含义

例子

-n

只打印模式匹配行,不打印原来的行(一般都会加该参数)

sed '/python/p' sed.txt

I love python

I love python

I love PYTHON

 

sed -n '/python/p' sed.txt

I love python

-e

直接在命令行进行sed编辑,默认选项(连接多个"pattern command"的组合)

sed -n -e '/pthon/p' -e '/PYTHON/p' sed.txt

-f

将匹配模式和命令的组合("pattern command")保存到文件中,指定文件执行

vim edit.sed

    /python/p

sed -n -f edit.sed sed.txt

-r

支持扩展正则表达式

sed -n -r '/python|PYTHON/p' sed.txt

-i

直接修改文件内容(sed默认不会对原文件进行修改)

sed -n -i 's/love/like/g;p' sed.txt

 

匹配模式(pattern)

  pattern匹配模式,即过滤条件,如果没有匹配模式,默认对所有行进行command处理,如果有匹配模式,先根据匹配模式过滤出相匹配的行,然后再对其逐行执行command

匹配模式

含义

10command

匹配到第10行

10,20command

匹配从第10行开始,到第20行结束

10,+5command

匹配从第10行开始,到第16行结束

/pattern1/command

匹配到包含pattern1的行(支持正则)

/pattern1/,/pattern2/command

匹配到包含pattern1的行开始,到匹配到包含pattern2的行结束

10,/pattern1/command

匹配从第10行开始,到匹配到包含pattern1的行结束

/pattern1/,10command

匹配到包含pattern1的行开始,到第10行结束

备注:$作为pattern时,表示最后一行

 

编辑命令(command)

类别

命令

含义

例子

查询

p

打印(默认命令)

 

增加

a

行后追加(匹配行后一行)

sed -i '/\/bin\/bash/a This is user which can login to system' /etc/passwd

i

行前追加(匹配行前一行)

sed -i '/\/bin\/bash/i This is user which can login to system' /etc/passwd

r

外部文件读入,行后追加(匹配行后一行追加外部文件的内容)

sed -i '/root/r list.txt' passwd

w

匹配行写入外部文件(将匹配到的行写入其他文件中)

sed -i '/root/w /tmp/user_login.txt' passwd

删除

d

删除

 

修改

s/old/new/

将行内第一个old替换成new

 

s/old/new/2

将行内第二个old替换成new

 

s/old/new/g

将行内全部的old替换成new

sed -i 's/\/bin\/bash/\/BIN\/BASH/g' passwd

s/old/new/2g

同一行内,替换从第2个开始到剩下所有符合条件的字符串

 

s/old/new/ig

将行内全部的old替换成new,忽略大小写

 

显示行号

=

查看行号,但不显示内容

显示包含/bin/bash的行的行号

sed -n '/\/bin\/bash/=' passwd

 

反向引用

  &和\1           引用模式匹配到的整个串

       &只能表示匹配到的完整字符串,只能引用整个字符串;而\1可以使用()来表示需要引用的字符串,并且\1可以扩展\2、\3等,顺序和前面()的顺序一致

举例

# 在test.txt文件中所有的had..p后面加入一个字符s,比如hadAAps、hadBBps
[root@VM_0_13_centos ~]# cat test.txt 
hadAAp is a bigdata frame
Spark hadBBp Kafka
Skill on hadCCp
Paper of hadDDp
Google hadEEp
# sed -i 's/\(had..p\)/\1s/g' test.txt与下面命令等价
[root@VM_0_13_centos ~]# sed -i 's/had..p/&s/g' test.txt 
[root@VM_0_13_centos ~]# cat test.txt 
hadAAps is a bigdata frame
Spark hadBBps Kafka
Skill on hadCCps
Paper of hadDDps
Google hadEEps

# 将上述修改过的文件中的s去除
[root@VM_0_13_centos ~]# sed -i 's/\(had..p\)s/\1/g' test.txt    
[root@VM_0_13_centos ~]# cat test.txt                         
hadAAp is a bigdata frame
Spark hadBBp Kafka
Skill on hadCCp
Paper of hadDDp
Google hadEEp

# 将上述修改后的文件中had..p中的两个字符改为II
[root@VM_0_13_centos ~]# sed -i 's/\(had\)..\(p\)/\1II\2/g' test.txt   
[root@VM_0_13_centos ~]# cat test.txt 
hadIIp is a bigdata frame
Spark hadIIp Kafka
Skill on hadIIp
Paper of hadI

 

sed中引用变量 

  1.匹配模式中存在变量,则建议使用双引号(推荐方法)

       2.sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号

举例

  以上两种方式任选其一,但是建议使用第一种方式,即pattern command使用双引号括起来,即"pattern command"

    #!/bin/bash
    old_str=hadoop
    new_str=HADOOP
   # 第一种方式 sed
-i "s/$old_str/$new_str/g" test.txt
   # 第二种方式 # sed
-i 's/'$old_str'/'$new_str'/g' test.txt

 

利用sed查询特定内容

  1.打印/etc/passwd中第20行的内容

              sed -n '20p' /etc/passwd

       2.打印/etc/passwd中从第8行开始,到15行结束的内容

              sed -n '8,15p' /etc/passwd

       3.打印/etc/passwd中从第8行开始,然后+5行结束的内容

              sed -n '8,+5p' /etc/passwd

       4.打印/etc/passwd中开头匹配hdfs字符串的内容

              sed -n '/^hdfs/p' /etc/passwd

       5.打印/etc/passwd中开头为root的行开始,到开头为hdfs的行结束的内容

              sed -n '/^root/,/^hdfs/p' /etc/passwd

       6.打印/etc/passwd中第8行开始,到含有/sbin/nologin的内容的行结束的内容

              sed -n '8,/\/sbin\/nologin/p' /etc/passwd

       7.打印/etc/passwd中第一个包含/bin/bash内容的行开始,到第5行结束的内容

              sed -n '/\/bin\/bash/,5p' /etc/passwd

利用sed删除特定内容

       1.删除/etc/passwd中的第5行

              sed -i '15d' /etc/passwd

       2.删除/etc/passwd中的第8行到第14行的所有内容

              sed -i '8,14d' /etc/passwd

       3.删除/etc/passwd中的不能登录的用户(筛选条件:/sbin/nologin)

              sed -i '/\/sbin\/nologin/d' /etc/passwd

       4.删除/etc/passwd中以mail开头的行,到以yarn开头的行的所有内容

              sed -i '/^mail/,/^yarn/d' /etc/passwd

       5.删除/etc/passwd中第一个不能登录的用户,到第13行的所有内容

              sed -i '/\/sbin\/nologin/,13d' /etc/passwd

       6.删除/etc/passwd中第5行到以ftp开头的所有行的内容

              sed -i '5,/^ftp/d' /etc/passwd

       7.删除/etc/passwd中以yarn开头的行到最后行的所有内容

              # $表示最后一行

              sed -i '/^ftp/,$d' /etc/passwd

       8.删除/etc/passwd中不能登录的所有用户

     sed -i "/\/sbin\/nologin/d" /etc/passwd 

       9.删除配置文件中的所有注释行和空行

    # 在sed中连续执行两个"pattern command",使用;连接,即"pattern1 command1;pattern2 command2"

              sed -i '/[:blank:]*#/d;/^$/d' /etc/nginx/nginx.conf

       10.在配置文件中所有不以#开头的行前面添加*字符,注意:以#开头的行不添加

              sed -i 's/^[^#]/\*&/g' /etc/nginx/nginx.conf

利用sed修改文件内容

修改命令对照表

编辑命令

含义

1s/old/new/

将第一行中的old替换成new

1,10s/old/new/

将第一行到第十行中的old替换成new

1,+5s/old/new/

将第一行到第六行中的old替换成new

/pattern1/s/old/new/

将匹配到pattern1的行中的old替换成new

/pattern1,/pattern2/s/old/new/

将匹配到pattern1的行直到匹配到pattern2的所有行中的old替换成new

/pattern1/,10s/old/new/

将匹配到pattern1的行到第10行的所有行中的old替换成new

10,/pattern1/s/old/new/

将第10行直到匹配到pattern1的行中的old替换成new

       修改/etc/passwd中第1行中第一个root为ROOT

              sed -i '1s/root/ROOT/' /etc/passwd

       修改/etc/passwd中第5行到第10行中所有的/sbin/nologin为/bin/bash

              sed -i '5,10s/\/sbin\/nologin/\/bin\/bash/g' /etc/passwd

       修改/etc/passwd中匹配到/sbin/nologin的行,将匹配到行中的login改为LOGIN

              sed -i '/\/sbin\/nologin/s/login/LOGIN/g' /etc/passwd

       修改/etc/passwd中从匹配到以root开头的行,到匹配到行中包含mail的所有行,将这些所匹配到的行中的bin改为HADOOP

              sed -i '/^root/,/mail/s/bin/HADOOP/g' /etc/passwd

       修改/etc/passwd中从匹配到以root开头的行,到第15行,将这些所匹配到的行中的nologin改为SPARK

              sed -i '/^root/,15s/nologin/SPARK/g' /etc/passwd

       修改/etc/passwd中从第15行,到匹配到以yarn开头的行,将这些所匹配到的行中的bin改为BIN

              sed -i '15,/^yarn/s/bin/BIN/g' /etc/passwd

利用sed追加文件内容

追加

a

行后追加(匹配行后一行)

sed -i '/\/bin\/bash/a This is user which can login to system' /etc/passwd

i

行前追加(匹配行前一行)

sed -i '/\/bin\/bash/i This is user which can login to system' /etc/passwd

r

外部文件读入,行后追加(匹配行后一行追加外部文件的内容)

sed -i '/root/r list.txt' passwd

w

匹配行写入外部文件(将匹配到的行写入其他文件中)

sed -i '/root/w /tmp/user_login.txt' passwd

 a

       1.passwd文件第10行后面追加“Add Line Behind”

              sed -i '10a Add Line Behind' passwd

       2.passwd文件第10行到第20行,每一行后面都追加“Test Line Behind”

              sed -i '10,20a Test Line Behind' passwd

       3.passwd文件匹配到/bin/bash的行后面追加“Insert Line For /bin/bash Behind”

              sed -i '/\/bin\/bash/a Insert Line For /bin/bash Behind '

 i

       1.passwd文件匹配到以yarn开头的行,在匹配行前面追加“Add Line Before”

              sed -i '/^yarn/i Add Line Before ' passwd

       2.passwd文件每一行前面都追加“Insert Line Before Every Line”

              sed -i 'i Insert Line Before Every Line' passwd

 r

       1.将/etc/fstab文件的内容追加到passwd文件的第20行后面

              sed -i '20r /etc/fstab' passwd

       2.将/etc/inittab文件内容追加到passwd文件匹配/bin/bash行的后面

              sed -i '/\/bin\/bash/r /etc/inittab' passwd

       3.将/etc/vconsole.conf文件内容追加到passwd文件中特定行后面,匹配以ftp开头的行,到第18行的所有行

              sed -i '/^ftp/,18r /etc/vconsole.conf' passwd

 w

       1.将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中

              sed -i '/\/bin\/bash/w /tmp/sed.txt' passwd

       2.将passwd文件从第10行开始,到匹配到hdfs开头的所有行内容追加到/tmp/sed.txt

              sed -i '10,/^hdfs/w /tmp/sed.txt' passwd

 

示例:处理一个类似MySQL配置文件my.cnf的文本,示例如下:

       编写脚本实现以下功能:输出文件有几个段([mysqld]这样是一个段),并且针对每个端可以统计配置参数总个数

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

# Settings user and group are ignored when systemd is used.

# If you need to run mysqld under a different user or group,

# customize your systemd unit file for mariadb according to the

# instructions in http://fedoraproject.org/wiki/Systemd

 

[mysqld_safe]

log-error=/var/log/mariadb/mariadb.log

pid-file=/var/run/mariadb/mariadb.pid

 

#

# include all files from the config directory

#

!includedir /etc/my.cnf.d

 

预想输出结果

       1: mysqld 3

       2: mysqld_safe 2

 

结构

       function get_all_segment

       {

              sed -n 's/^\[\(.*\)\]$/\1/p' /etc/my.cnf

       }

       function count_items_in_segment

       {

              sed -n '/^\['$1'\]$/,/^\[.*\]$/p' /etc/my.cnf | grep -vE "^#|^$|^\[.*\]$|^\!"|wc -l

       }

 

代码

[root@VM_0_13_centos ~]# cat mysql_process.sh

#!/bin/bash

 

 

FILE_NAME=/etc/my.cnf

 

function get_all_segment

{

        echo "`sed -n 's/^\[\(.*\)\]$/\1/p' $FILE_NAME`"

}

 

function count_items_in_segment

{

        echo "`sed -n '/^\['$1'\]$/,/^\[.*\]$/p' $FILE_NAME | grep -vE "^#|^$|^\[.*\]$|^\!"|wc -l`"

}

 

index=1

for segment in `get_all_segment`

do

        items_count=`count_items_in_segment $segment`

        echo "$index: $segment $items_count"

        index=`expr $index + 1`

done

[root@VM_0_13_centos ~]# sh mysql_process.sh 

1: mysqld 3

2: mysqld_safe 2

posted @ 2019-03-10 23:37  小宇子2B  阅读(179)  评论(0)    收藏  举报