sed(二)

sed -i代表插入 N代表行 2a代表下一行  
sed -i代表插入 N代表行 2i代表上一行  


★指定内容后面添加,注意中间有一个分开的a,待匹配的文中若遇到正划杠,就得加一个转义

a:如果是a就是在匹配到内容的下一行添加 
i:如果是i就是在匹配到内容的上一行添加


【1】在指定的行后面或者是前面追加一行,这个时候可以使用sed来完成,具体用法如下
a\: 在指定的行后面追加一行
i\: 在指定的行前面追加一行


1,初始化
cat >/etc/resolv.conf<<EOR
192.168.2.0
192.168.2.1
192.168.2.2
192.168.2.3
192.168.2.4
192.168.2.5
192.168.2.6
EOR


2,指定添加到某行
a代表下一行 
解释:sed -i代表插入 N代表行 2a代表下一行   意思就是在第二行的后面插入。
sed -i 'N;2a\nameserver 192.168.2.70 ' /etc/resolv.conf 
sed  'N;2a\nameserver 192.168.2.70 ' /etc/resolv.conf 

显示:
[root@centos]# cat -n /etc/resolv.conf
     1  192.168.2.0
     2  192.168.2.1
     3  nameserver 192.168.2.70
     4  192.168.2.2
     5  192.168.2.3
     6  192.168.2.4
     7  192.168.2.5
     8  192.168.2.6

N;后面只能使用偶数,且N不可以为0。

下面的命令执行后,什么都没有修改:
sed -i 'N;1a\nameserver 192.168.2.7x ' /etc/resolv.conf 
sed -i 'N;3a\nameserver 192.168.2.7x ' /etc/resolv.conf 
sed -i 'N;5a\nameserver 192.168.2.7x ' /etc/resolv.conf 


3,如果不带N参数,可以随意插到指定的行.
sed -i '1a\nameserver 192.168.2.69 ' /etc/resolv.conf 
sed -i '3a\nameserver 192.168.2.70 ' /etc/resolv.conf 


[root@localhost ~]# cat -n /etc/resolv.conf
     1  192.168.2.0
     2  nameserver 192.168.2.69
     3  192.168.2.1
     4  192.168.2.2
	 
4,在第二行的前面插入一行
sed  '2i\nameserver 192.168.2.72 ' /etc/resolv.conf
第7行的前面插入
sed -i '7i\newline2'  /etc/resolv.conf



【2】匹配字符串,然后替换。

sed -i '/匹配的字符串/a 替换的字符串' 匹配文件
sed -i '/aaa/a testtest.net' /shell/test.txt
sed -i '/匹配的字符串/i 替换的字符串' 匹配文件
sed -i '/aaa/i testtest.net' /shell/test.txt

初始化
cat >/shell/test.txt<<EOR
aaa
bbb
ccc
ddd
extension_dir
EOR


1,在匹配到了的aaa内容的下一行添加testtest.net
[root@localhost nagios]# sed -i '/aaa/a testtest.net' /shell/test.txt

[root@localhost ~]# cat -n /shell/test.txt
     1  aaa
     2  testtest.net
     3  bbb
     4  ccc
     5  ddd
     6  extension_dir

2,在extension_dir内容下添加一行extension="redis.so"
sed -i '/extension_dir/aextension="redis.so"'  /shell/test.txt
[root@localhost ~]# cat -n /shell/test.txt
     1  aaa
     2  testtest.net
     3  bbb
     4  ccc
     5  ddd
     6  extension_dir
     7  extension="redis.so"

3,在匹配到了的aaa内容的上一行添加testtest.net
[root@localhost nagios]# sed -i '/aaa/i testtest.net' /shell/test.txt


4,原始
[root@localhost ~]# cat -n /shell/test.txt
     1  aaa
     2  bbb
     3  ccc
     4  ddd
     5  cfg_file=/usr/local/nagios/etc/objects/templates.cfg

例、
需求:在第5行下面添加两行

分别是
      cfg_file=/usr/local/nagios/etc/objects/services.cfg
      cfg_file=/usr/local/nagios/etc/objects/hosts.cfg

操作
      sed -i '/匹配原文/a 新文' /shell/test.txt
注意如果是a就是在匹配到内容的下一行添加,下文需要添加一个转义。

sed -i '/cfg_file=\/usr\/local\/nagios\/etc\/objects\/templates.cfg/a cfg_file=/usr/local/nagios/etc/objects/services.cfg' /shell/test.txt
sed -i '/cfg_file=\/usr\/local\/nagios\/etc\/objects\/templates.cfg/a cfg_file=\/usr\/local\/nagios\/etc\/objects\/services.cfg' /shell/test.txt


例二、处理当前行结尾为反斜杠\情况
需求:
想在ExecStart=/usr/bin/dockerd-current \下添加一行源
效果为:--registry-mirror=http://e2ac17b9.m.daocloud.io \

公式
sed -i '/匹配原文/a 新文' /shell/test.txt
•下述2种方法都可以,但是,使用双引号可以应对文中有shell变量的情况。
使用单引号:sed  '/ExecStart=\/usr\/bin\/dockerd-current /a --registry-mirror=http://e2ac17b9.m.daocloud.io \\' /shell/test.txt
使用双引号:sed  "/ExecStart=\/usr\/bin\/dockerd-current /a --registry-mirror=http://e2ac17b9.m.daocloud.io \\\\" /shell/test.txt

【3】替换高级

公式格式:
sed 's/要替换的字符串/新的字符串/g'   
sed "s/要替换的字符串/新的字符串/g"
sed "s@要替换的字符串@新的字符串@g"


公式一、(分割符为/正斜扛)
sed 's/要替换的字符串/新的字符串/g'   (要替换的字符串可以用正则表达式)

公式二、(分割符为@正斜扛) 这个符号是可以自定义的。
sed -i "s@^LimitRecursion.*@LimitRecursion  65535 8@" /shell/pure-ftpd.conf

公式格式:
1、sed 's/要替换的字符串/新的字符串/g'  
2、sed -i 's/要替换的字符串/新的字符串/g'

3、单双引号问题:如果有一个变量,外面再用单引号,无法解析
解决方法,就是双引号,套双引号,里面的双引号加一个反斜杠

4、只要遇到正斜杠都得在它前面加个反斜杠

5、当双引号套双引号时,需要加反反斜杠


######################################
1,初始化
cat >/shell/test.txt<<EOR
aaa
'/zj/web/'
ccc
ccc
ddd
run_as_user=''
EOR


2,双引号,解析变量

公式格式:sed 's/要替换的字符串/新的字符串/g' 

替换的内容run_as_user=''
替换后的结果 run_as_user='root'

sed "s@run_as_user=''@run_as_user='root'@g"  /shell/test.txt,
sed -i "s@run_as_user=''@run_as_user='root'@g" /shell/test.txt

▶变量的方式
old_str="run_as_user=''"
new_str="run_as_user='root'"

sed -i "s@${old_str}@${new_str}@g" /shell/test.txt
sed  "s@${old_str}@${new_str}@g" /shell/test.txt


3、单双引号问题:如果有一个变量,外面再用单引号,无法解析
#单引号,不解析变量 在这里它会判断为一个${}是一个字符串,到文本中去查找。
例一、
old_str='ccc'
new_str='taobaozx.net'
sed -i 's@${old_str}@${new_str}@' /shell/test.txt

执行
[root@localhost ~]# old_str='ccc'
[root@localhost ~]# new_str='taobaozx.net'
[root@localhost ~]# sed -i "s@${old_str}@${new_str}@" /shell/test.txt

######################################
1,初始化
cat >/shell/test.txt<<EOR
aaa
'/zj/web/'
ccc
ccc
ddd
run_as_user=''
# server.host: "0.0.0.0"
EOR

2,当双引号,套双引号时需要加反反斜杠
例如
# server.host: "0.0.0.0"
想替换成
server.host: "127.0.0.0"

方法一
    公式
    sed "s/要替换的字符串/新的字符串/g"
    sed  "s/# server.host: \"0.0.0.0\"/server.host: \"127.0.0.0\"/g"  /shell/test.txt

方法二  
    公式
    sed "s@要替换的字符串@新的字符串@g"
    sed "s@# server.host: \"0.0.0.0\"@server.host: \"127.0.0.0\"@g" /shell/test.txt
######################################
演示:双引号,套双引号,里面的双引号加一个反斜杠
例二、特殊情况下的双引号之解决方法:正斜扛转义

▶需求:
将'/zj/web/'     替换成    'taobaozx.net' \

方法一
公式
sed "s/要替换的字符串/新的字符串/g"
        ▶过程化
            sed "s/'\/zj\/web\/'/'taobaozx.net'/g" /shell/test.txt   #后面少个反斜杠

            #双扛\\/换一扛\
            sed "s/'\/zj\/web\/'/'taobaozx.net' \\\/g" /shell/test.txt  #正确处理

		▶脚本中的变化
            old_str="'\/zj\/web\/'"    
            new_str="'taobaozx.net' \\\\"
            sed "s/要替换的字符串/新的字符串/g" /shell/test.txt
            sed "s/${old_str}/${new_str}/g"  /shell/test.txt
            sed "s/$old_str/$new_str/g"  /shell/test.txt
 


方法二  这种方法要好看些  当遇到复杂的就比较实用
公式
sed "s@要替换的字符串@新的字符串@g"
        ▶过程化
            old_str="'\/zj\/web\/'"    
            new_str="'taobaozx.net' \\\/"

            第一步
            sed "s@'\/zj\/web\/'@'taobaozx.net'@g"  /shell/test.txt  #缺一个转义

            第二步
            sed "s@'\/zj\/web\/'@'taobaozx.net' \\\@g"  /shell/test.txt


        ▶脚本中的变化
            第三步,做成变量   注意转义
            old_str="'\/zj\/web\/'"    
            new_str="'taobaozx.net' \\\\"
            sed "s@要替换的字符串@新的字符串@g"  /shell/test.txt
            sed "s@$old_str@${new_str}@g"  /shell/test.txt

【4】 其它

规则:
1、在替换中遇到双引号,需要加反斜扛进进转义。
2、在替换中遇到http://中的两个正斜扛也需要进行转义。


目标字段

    # server.port: 5601
    # server.host: "0.0.0.0"
    # elasticsearch.url: "http://localhost:8000"

换成
     server.port: 5601
     server.host: "192.168.1.163"  
     elasticsearch.url: "http://192.168.1.250:8000"


sed "s@要替换的字符串@新的字符串@g"  /shell/test.txt
sed "s@# server.port: 5601@server.port: 5601@g"  /shell/test.txt
sed "s@# server.host: \"0.0.0.0\"@server.host: \"192.168.163\"@g"  /shell/test.txt
sed "s@# elasticsearch.url: \"http://localhost:8000\"@elasticsearch.url: \"http:\/\/192.168.1.2:8000\"@g"  /shell/test.txt
sed "s@# elasticsearch.url: \"http://localhost:8000\"@elasticsearch.url: "http://192.168.1.2:8000"@g"  /shell/test.txt

  

 

  

posted @ 2019-06-16 18:31  山的那一边  阅读(192)  评论(0)    收藏  举报