sed(Stream Editor)

流编辑器。对标准输出或文件逐行进行处理

语法格式(类似grep):sed [ -nefri ] "pattern command"

常用选项

选项:-n 只打印模式匹配行

在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

选项:-e 直接在命令行进行sed编辑,默认选项

选项:-f  编辑动作保存在文件中,指定文件执行

选项:-r 支持扩展正则表达式

选项:-i 直接修改文件内容

常用编辑命令

a  ∶新增, a 的后面可以接字串,行后追加

c  ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!

d  ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;

i  ∶插入, i 的后面可以接字串。行前追加;

p  ∶打印,亦即将某个选择的内容输出。通常 p 会与参数 sed -n 一起用

s  ∶取代,可以直接进行修改工作!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 

g  :在行内进行全局替换

r  :外部文件读取,行后追加

注意s后面的分隔符不一定是/也可指定为其他,例如@ 。 s@aa@bb@g

第一种形式

sed [option] "pattern command " file
vim 1.txt

I love php
I love PHP
I love python
I love PYTHON
I love p.*
Hadoop is bigdata frame

1、默认sed会自带p命令、在次用p会打印两边

[root@docker-host sh]# sed "/python/p" 1.txt
I love php
I love PHP
I love python
I love python
I love PYTHON
I love p.*
Hadoop is bigdata frame

p会-n连用

[root@docker-host sh]# sed -n "/python/p" 1.txt
I love python

2、多次处理用-e

[root@docker-host sh]# sed -n -e '/python/p' -e '/PYTHON/p' 1.txt
I love python
I love PYTHON

3、处理表达式保存到文件执行 -f

vim edit.sed

/python/p


[root@docker-host sh]# sed -n -f edit.sed  1.txt
I love python
[root@docker-host sh]#

4、使用扩展表达式 -r

##不使用扩展正则表达式
[root@docker-host sh]# sed -n  "/python|PYTHON/p"  1.txt
##使用扩展表达式
[root@docker-host sh]# sed -n  -r "/python|PYTHON/p"  1.txt
I love python
I love PYTHON

5、直接修改文件 -i

结合 s命令用 s/love/like/g;p这种格式。命令连接处用;隔离

[root@docker-host sh]# sed -n 's/love/like/g;p' 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
[root@docker-host sh]# cat 1.txt
I love php
I love PHP
I love python
I love PYTHON
I love p.*

没有加-i参数前  源文件没有变化
加上-i参数后

[root@docker-host sh]# sed -n  -i 's/love/like/g;p' 1.txt
[root@docker-host sh]# cat 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

第二种形式

stdout #标准输出 | sed [option] "pattern command"

send中的pattern详解

模式:10command 匹配到第10行

1、LineNumber           ---直接指定行号
sed -n "3p" 1.txt     打印1.txt中的第三行

[root@docker-host sh]# sed -n "3p" 1.txt
I like python

模式:5,6comand 匹配从第5行开始,到第6行结束

2、StartLine,EndLine    ---打印起始行号,到结束行号
sed -n "5,6p" 1.txt

[root@docker-host sh]# sed -n '5,6p' 1.txt
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#

模式:4,+2comand 匹配从第4行开始,到第6行结束

3、StartLine,+N     -----打印起始行号到,加上的行号
[root@docker-host sh]# sed -n '4,+2p' 1.txt
I like PYTHON
I like p.*
Hadoop is bigdata frame

模式:/pattern1/command 匹配到pattern1的行

----正则表达式匹配的行
[root@docker-host sh]# sed -n '/php/p' 1.txt
I like php

----用sed查找电脑中禁止登录的用户

[root@docker-host sh]# sed -n '/\/sbin\/nologin/p' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
......
......

模式:/pattern1/,/pattern2/command 匹配到pattern1行开始,到匹配到pattern2的行结束

从sshd的行到vagrant的行结束

[root@docker-host sh]# sed -n '/^sshd/,/^vagrant/p' /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:995::/var/lib/chrony:/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
[root@docker-host sh]#

模式:21,/pattern1/command 匹配从第21行开始,到匹配到pettern1行结束

[root@docker-host sh]# sed -n '21,/^vagrant/p' /etc/passwd
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:995::/var/lib/chrony:/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash

模式:/pattern1/,5command 匹配到pattern1的行开始,到文本开始的第5行匹配结束

[root@docker-host sh]# sed -n '/root/,5p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@docker-host sh]#

图

###从开始匹配,到文本的第三行结束来匹配图片的结果
[root@docker-host sh]# sed -n '/adm/,3p' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin

结果是如果要求所在行数没有符合要求,继续向下匹配成功后返回当前行

sed编辑命令详解

编辑命令:d 删除

####  d 删除命令 、例子用的还是上文中的1.txt
[root@docker-host sh]# sed -n 'p' 1.txt
I like php
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]# sed -n '1d;p' 1.txt
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]

[root@docker-host sh]# sed -n '1,3d;p' 1.txt
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#

删除passwd文件里面的nologin用户

[root@docker-host sh]# sed -i '/\/sbin\/nologin/d' ./passwd

编辑命令:a 追加内容行

####删除1.txt的第一行 、匹配大写PHP的行在后面追加sha
[root@docker-host sh]# sed  '1d;/PHP/a sha' 1.txt
I like PHP
sha
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

编辑命令:i 之前的追加

[root@docker-host sh]# sed  '/php/,/PHP/i sha' 1.txt
sha
I like php
sha
I like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

编辑命令:r 将后面指定文件内容追加到匹配到的行后面

vim sed.txt

First Line (11111)
Second Line (22222)

[root@docker-host sh]# sed '/python/r sed.txt' 1.txt
I like php
I like PHP
I like python
First Line (11111)
Second Line (22222)
I like PYTHON
I like p.*
Hadoop is bigdata frame

编辑命令:w将匹配到的行内容另存到其他文件中

[root@docker-host sh]# sed  -n '/python/w wirte.txt' 1.txt
[root@docker-host sh]# ls wirte.txt
wirte.txt
[root@docker-host sh]#vim  wirte.txt

I like python

编辑命令:s 修改

修改1.txt、改成如下内容

vim  1.txt

I like php,I really like php ,very like php
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

例子

查找符合/tattern模式的字符并进行替换(加g是全局替换)
s/pattern/string/g

[root@docker-host sh]# sed   's/php/PHP_/g' 1.txt
I like PHP_,I really like PHP_ ,very like PHP_
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

查找符合 s/pattern/string/2g模式的字符进行替换
2g代表从行内第二个开始替换的意思
[root@docker-host sh]# sed   's/php/_PHP/2g' 1.txt
I like php,I really like _PHP ,very like _PHP
I like PHP,,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

s/pattern/string/3gi不区分大小写,i有多重含义/*/*/是不区分大小写的
[root@docker-host sh]# sed   's/php/_PHP/3gi' 1.txt
I like php,I really like php ,very like _PHP
I like PHP,,I really like PHP ,very like _PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

编辑命令:= 显示行号

[root@docker-host sh]# sed  -n '/php/=' 1.txt
1
[root@docker-host sh]#

方向引用

& 给PHP后面加上$ 。&等同于\0

[root@docker-host sh]# sed   's/php/&$/ig' 1.txt
I like php$,I really like php$ ,very like php$
I like PHP$,I really like PHP$ ,very like PHP$
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

[root@docker-host sh]# sed   's/php/\0$&/ig' 1.txt
I like php$php,I really like php$php ,very like php$php
I like PHP$PHP,I really like PHP$PHP ,very like PHP$PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

[root@docker-host sh]#  echo -e "2017 2016 2018" | sed -e "s/\(.*\) \(.*\) \(.*\)/\2 \1 \3/g"
2016 2017 2018
[root@docker-host sh]#
把通过正则反向引用的方式
[root@docker-host sh]# sed   's/\(p\).p/\1ython/ig' 1.txt
I like python,I really like python ,very like python
I like Python,I really like Python ,very like Python
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame

#!/usr/bin/env bash

old_str=php
new_str=PHP

sed -i "s/$old_str/$new_str/g" 1.txt

[root@docker-host sh]# sh sed_sample.sh
[root@docker-host sh]# cat 1.txt
I like PHP,I really like PHP ,very like PHP
I like PHP,I really like PHP ,very like PHP
I like python
I like PYTHON
I like p.*
Hadoop is bigdata frame
[root@docker-host sh]#

如果使用单引号、需要拼接

sed -i 's/'$old_str'/'$new_str'/g' 1.txt

sed查找特定内容

配置文件代码

[myisamchk]
key_buffer_size = 20M
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
explicit_defaults_for_timestamp=true
skip-external-locking
key_buffer_size=16M
max_allowed_packet=1M
table_open_cache=64
sort_buffer_size=512K
net_buffer_length=8K
read_buffer_size=256K
read_rnd_buffer_size=512K
myisam_sort_buffer_size=8M
user=mysql
character_set_server=utf8
skip-character-set-client-handshake
lower_case_table_names=1
interactive_timeout=120
group_concat_max_len=10240
skip-external-locking
open_files_limit=65000
innodb_open_files=50000
back_log=300
max_connections=1500
max_connect_errors=100000
tmp_table_size=96M
max_heap_table_size=96M
innodb_buffer_pool_size=4096M
innodb_flush_log_at_trx_commit=1
sync_binlog=1
innodb_file_per_table=1
innodb_log_files_in_group=2
long_query_time=2
slow_query_log=1
slow_query_log_file=/usr/local/mysql/data/slow_query.log
[client]
port=3306
socket=/usr/local/mysql/mysql.sock
[mysql]
default-character-set=utf8
[myisamchk]
key_buffer_size=20M
sort_buffer_size=20M
read_buffer=2M
write_buffer=2M
[mysqlhotcopy]
interactive-timeout

注意第一个配置行【myisamchk】的配置项由于有空格、统计出了3个配置

#!/usr/bin/env bash

FILE_NAME=/home/vagrant/labs/sh/my.cnf

function get_all_segment
{
    echo `sed  -n '/\[.*\]/p' ${FILE_NAME} | sed -e 's/\[//g' -e 's/\]//g'`
}

function count_items_in_segment
{
    items=`sed  -n "/\[$1\]/,/\[.*\]/p" ${FILE_NAME} | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]"`
    index=0
    for item in ${items}
    do
        index=`expr ${index} + 1`
    done

    echo ${index}

}
number=0
for seg in `get_all_segment`
do
    number=`expr ${number} + 1`
    echo "${number}:配置项:$seg 。数量:`count_items_in_segment $seg `"
done

sed删除特定内容

1d  删除第一行内容
1,10d删除1行到10行的内容
1,+5d 删除1行到6行的内容
/pattern1/d  删除每行中匹配到pattern1的行内容
/pattern1/,/pattern2/d  删除酦醅到pattern1行。直到匹配到pattern2的所有行内容
/pattern1/,10d   删除匹配到pattern1的行到第10行的所有行内容
10,/pattern1/d  删除第10行直到匹配到pattern1的所有内容

练习例子

cp /etc/passwd ./

1、删除/etc/passwd中的第15行
sed -i '15d' /etc/passwd

2、删除/etc/passwd中的第8行到第14行的所有内容
sed -i '8,14d' passwd

3、删除/etc/passwd中的不能登录的用户
sed -i '/\/sbin\/nologin/d' passwd

4、删除/etc/passwd中以mail开头的行,到以yarn开头的行的所有内容
sed -i '/^mail/,/^yarn/d' passwd

5、删除/etc/passwd中不能登录的用户,到匹配出所有符合条件的13条行记录的所有内容
sed -i '/\sbin\/nologin/,13d' passwd

6、删除/etc/passwd中第5行到以ftp开头的所有行的内容
sed -i '5,/^ftp/d' passwd

7、删除/etc/passwd中以yarn开头的行到最后行的所有内容
sed -i  '/^yarn/,$d' passwd

实际案例

nginx.conf

#nginx配置文件
user  vagrant;
worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    autoindex       on;
    sendfile        on;
    charset      utf-8;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        #root /usr/local/nginx/html;
        root /home/vagrant/labs/swoole;
        #access_log  logs/host.access.log  main;
        location / {
            add_header Access-Control-Allow-Origin \*;
            add_header Access-Control-Allow-Headers DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
            if ($request_method = 'OPTIONS') {
                return 204;
            }
            index  index.php index.html;
        }
        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location ~ .+\.php.*$ {
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
            fastcgi_param  SCRIPT_FILENAME  $request_filename;
            include  fastcgi_params;
            fastcgi_param HTTPS on;
        }

    }

    include /usr/local/openresty/nginx/conf.d/*.conf;
}

删除\#为开头的注释行

[root@docker-host sh]# sed -n '/[:blank:]*#/p' nginx.conf

打印出内容

[root@docker-host sh]# sed -n '/[:blank:]*#/p' nginx.conf
#nginx配置文件
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
        #root /usr/local/nginx/html;
        #access_log  logs/host.access.log  main;
        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
[root@docker-host sh]#

删除#注释和空行

[root@docker-host sh]# sed -i '/[:blank:]*#/d;/^$/d' nginx.conf
*表示0个或多个、那么就是开头是#或者前面有多个空格的#开头的行,和空行

sed修改特定的内容

替换第一行内容old为new
1s/old/new/  

替换1行到10行的内容old为new
1,10s/old/new/ 

替换1行到6行的内容old为new 
1,+5s/old/new/   

替换匹配到pattern1的行内容old为new
/pattern1/s/old/new/ 

替换匹配到pattern1的行直到匹到pattern2的所有行内容old为nenw
/pattern1/,/pattern2/s/old/new/ 


替换第10行直到匹配到pattern1的所有行内容old的为new
10,/pattern1/s/old/new/

练习例子

1、修改/etc/passwd中第1行中第一个root为ROOT
sed -i '1s/root/ROOT/g' passwd

2、修改/etc/passwd中第5行到第10行中所有的/sbin/nologin为/bin/bash
sed -i "5,10s/\/sbin\/nologin/\/bin\/bash/" passwd

3、修改/etc/passwd中匹配到/sbin/nologin的行,将匹配到行中的login改为大写的LOGIN
sed -i "/\/sbin\/nologin/s/login/LOGIN/g" passwd

4、修改/etc/passwd中批到以root开头的行,到匹配到行中包含mail的所有行。
讲这些所匹配到的行中的bin换成HADOOP
sed -i '/^root/,/mail/s/bin/HAOOP/g' passwd

5、修改/etc/passwd中从匹配到以root开头的行,到第15行中的所有行。把nologin改成SPARK
sed -i '/^root/,15s/nologin/SOARK/g' passwd

sed追加内容用法

a 在匹配行后面追加

1、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 Begind' passwd
 (3)、passwd文件匹配到/bin/bash的行后面追加"Insert Line For /bin/bash Behind"
    sed -i '/\/bin\/bash/a Insert Line  For /bin/bash  Begind' passwd

i 在匹配行前面追加

2、i
 (1)、passwd文件匹配到以mail开头的行,在匹配行前追加"Add Line Before"
     sed -i '/^mail/i Add Line Before' passwd
 (2)、passwd文件每一行前面都追加"Insert Line Before Every Line"
     sed  -i  'i Insert Line Before Every Line' passwd

r 将后面指定文件内容追加到匹配到的行后面

3、r
  (1)、将/etc/fatab文件的内容追加到passwd文件的第20行后面
     sed -i '20r /etc/fstab' passwd
  (2)、将/etc/inittab文件内容追加到passwd文件匹配/sbin/nologin行的后面
     sed -i '/\/sbin\/nologin/r /etc/inittab' passwd
  (3)、将/etc/vconsole.conf文件内容追加到passwd文件中特定行后面,
     匹配以mail开头的行,到第18行的所有行
     sed -i '/^mail/,18r /etc/vconsole.conf' passwd

w 将匹配到的行内容另存到其他文件中

4、w
  (1)、将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中
    
       sed -i '/\/bin\/bash/w sed.txt' passwd

  (2)、将passwd文件从第10行开始,到匹配到rpc开头结束的的所有行内容追加到
   /tmp/sed-1.txt
       sed -i '10,/^rpc/w sed.txt' passwd
Last modification:February 1, 2020
如果觉得我的文章对你有用,请随意赞赏