• linux三剑客之sed深度实践


    参数:

    -a:追加文本到指定行后

    -i:插入文本到指定行前

    1、单行增加

    [root@redhat~]#   sed  ' 2a  6,f '  linux.tet

    1,a

    2,b

    6,f

    3,c

    4,d

    5,e

    [root@redhat~]#   sed  ' 2i  6,f '  linux.tet

    1,a

    6,f

    2,b

    3,c

    4,d

    5,e

    2、多行增加

    [root@redhat~]#   sed  ' 2a  6,f 7,g '  linux.tet

    1,a

    2,b

    6,f        #-->第一种写法

    7,g

    3,c

    4,d

    5,e

    [root@redhat~]#   sed  ' 2a  6,f 

    >  7,g '  linux.tet

    1,a

    2,b

    6,f        #第二种写法

    7,g

    3,c

    4,d

    5,e

    #-->sed命令i的使用方法是一样的,因此不再列出。

    企业案例:优化SSH配置(一键完成增加若干参数)

    系统优化时,有一个优化点:更改ssh服务远程登录的配置。主要的操作是在ssh的配置文件加入下面5行文本。

    1.Port  52113

    2.PermitRootlogin  no

    3.PermitEmptyPasswords  no

    4.UseDNS  no

    5.GssAPIAuthentication  no

    我们可以使用vi命令编辑这个文本,但这样就比较麻烦,现在想一条命令增加5行文本到第13行前?

    指定执行的地址范围

    1.sed软件可以对单行或多行进行处理。如果在sed命令前面不指定地址范围,那么默认会匹配所有行

    2.用法,n1[,n2]{sed-commands}

    3.地址用逗号分隔的,n1,n2可以用数字、正则表达式、或二者的组合表示

    4.例子:

    1)10{sed-commands}        对第10行操作

    2)10,20{sed-commands}        对第10到20行操作,包括第10,20行

    3)10,+20{sed-commands}        对第10到30(10+20)行操作,包括第10,30行

    4)1~2{sed-commands}        对第1,3,5,7......行操作

    5)10,  ${sed-commands}        对第10到最后一行($代表最后一行)操作,包括第10行

    6)/redhat/{sed-commands}        对匹配redhat的行操作

    7)/redhat/,/linux/{sed-commands}        对匹配redhat的行到匹配linux的行操作

    8)/redhat/,${sed-commands}        对匹配redhat的行到最后一行操作

    9)/redhat/,10{sed-commands}        对匹配redhat的行到第10行操作,注意,如果前10行没有匹配到redhat,sed软件会显示10行以后的匹配redhat的行,如果有

    10)1,/redhat/{sed-commands}        对第1行到匹配redhat行的操作

    11)/redhat/ ,+2{sed-commands}        对匹配redhat的行到其后的2行操作

    3、删

    d:删除指定的行

    [root@redhat~]#   sed  ' d '  linux.tet     #-->删除所有

    [root@redhat~]#   sed  ' 2d '  linux.tet

    1,a

    3,c

    4,d

    5,e

    [root@redhat~]#   sed  ' 2,5d '  linux.tet

    1,a

    [root@redhat~]#   sed  ' 1~2d '  linux.tet

    2,b

    4,d

    [root@redhat~]#   sed  ' 1,+2d '  linux.tet

    4,d

    5,e

    [root@redhat~]#   sed  ' /redhat/d '  linux.tet     #-->删除包含“wuyang”的行

    1,wuyang,a

    4、改

    1)按行替换

    c:用新行取代旧行

    [root@redhat~]#   sed  ' 2c  6,f '  linux.tet

    1,a

    6,f

    3,c

    4,d

    5,e

    2)文本替换

    s:单独使用-->将每一行中第一处匹配的字符串进行替换==>sed命令

    g:每一行进行全部替换==>sed命令s的替换标志之一,非sed命令

    -i:修改文件内容==>sed软件的选项

    sed软件替换模型(a被替换成b)

    sed  -i  ' s/a/b/g '  redhat.log

    sed  -i  ' s#a#b#g '  redhat.log

    观察特点

    1.两边是引号,引号里面的两边分别为s和g,中间是三个一样的字符/或#作为定界符。#能在替换内容包含/有助于区别。定界符可以是任意符号如 : 或 | 等,但当替换内容包含定界符时,需要转义即:|。经过长期实践,建议大家使用#作为定界符。

    2.定界符/或#,第一个和第二个之间的就是被替换的内容,第二个和第三个之间的就是替换后的内容。

    3.s#a#b#g,a能用正则表达式,但b不能用,必须是具体的。

    4.默认sed软件是对模式空间(内存中的数据)操作,而-i选项会更改磁盘上的文件内容。

    企业案例:指定行修改配置文件

    指定行精确修改配置文件,这样可以防止修改所多了地方。

    [root@redhat~]#   sed  ' 3s#3#9# '  linux.tet

    1,a

    2,b

    9,c

    4,d

    5,e

    3)变量替换

    [root@redhat~]#   cat  test.txt  #-->创建一个文本

    a

    b

    a

    [root@redhat~]#  x=a

    [root@redhat~]#  y=b

    [root@redhat~]#  echo  $x  $y

    a  b

    [root@redhat~]#  sed  s#$x#$y#g  test.txt

    b

    b

    b

    [root@redhat~]#  sed  's#$x#$y#g'  test.txt

    a

    b

    a

    [root@redhat~]#  sed  "s#$x#$y#g"  test.txt

    b

    b

    b

    4)分组替换( )和1的使用说明

    sed软件的( )的功能可以记住正则表达式的一部分,其中,1为第一个记住的模式即第一个小括号中的匹配内容,2第二记住的模式,即第二个小括号中的匹配内容,sed最多可以记住9个。

    例:echo  I  am  student.如果想保留这一行的单词student,删除剩下的部分,使用圆括号标记想保留的部分。

    [root@redhat~]#  echo  I  am  student. | sed  ' s#^.*am  ([a-z].*)  stu.*$#1#g '

    student

    [root@redhat~]#  echo  I  am  student. | sed  -r  ' s#^.*am  ([a-z].*)  stu.*$#1#g '

    student

    1. ^.*am-->这句的意思是以任意字符开头到am 为止,匹配文件中的I  am 字符串

    2. ([a-z].*)-->这句的外壳就是括号( ),里面的[a-z]表示匹配26个字母的任何一个,[a-z].*合起来就是匹配任意多个字符,本题来说就是匹配student字符串,由于student字符串是需要保留的,因此用括号括起来匹配,后面通过1来取student字符串

    3. stu.*$-->表示以空格tea起始,任意字符结尾,实际就是匹配student字符串后,紧接着的字符串student

    4.后面被替换的内容中的1就是取前面的括号里的内容了,也就是我们要的student字符串

    5、()是扩展正则表达式的元字符,sed软件默认识别基本正则表达式,想要使用扩展正则需要使用转义,即( )。sed使用-r选项则可以识别扩展正则表达式,此时使用( )反而会出错

     企业案例:系统开机启动项优化

    [root@redhat~]#  chkconfig  --list | grep  "3:on" | grep  -vE  "sshd | crond | network | rsyslog | sysstat" | awk  ' {print  $1} ' | sed  -r  ' s#^(.*)#chkconfig  1  off#g ' | bash

    [root@redhat~]#  chkconfig  --list | grep  "3:on"

     5)特殊符号&代表被替换的内容

    [root@redhat~]#  sed  '1,3s#c#--&--#g'  redhat.txt     #-->此处&等于c

    1,a,--c--eo

    2,b,--c--to

    3,c,--c--oo

    4,d,cfo

    5,e,cio

    企业案例:批量重命名文件

    当前目录下有文件如下所示:

    [root@redhat~]#  ls

    stu_10_1_a.jpg   stu_10_2_a.jpg   stu_10_3_a.jpg   stu_10_4_a.jpg   stu_10_5_a.jpg

    要求用sed命令重命名,效果为stu_10_1_a.jpg==>stu_10_1.jpg,即删除文件名的_a

    [root@redhat~]#  ls  *.jpg | sed  -r  's#(^.*)_a.*#mv & 1.jpg#g' | bash

    5、查

    p:输出指定内容,但默认会输出2次匹配的结果,因此使用n取消默认输出

    1)按行查询

    [root@redhat~]#   sed  ' 2p '  linux.txt

    1,a

    2,b

    2,b

    3,c

    4,d

    5,e

    [root@redhat~]#   sed  -n  ' 2p '  linux.txt

    2,b

    [root@redhat~]#   sed  -n  ' 2,3p '  linux.txt

    2,b

    3,c

    说明:取行就用sed,最简单

    [root@redhat~]#   sed  -n  ' 1~2p '  linux.txt

    1,a

    3,c

    5,e

    [root@redhat~]#   sed  -n  ' p '  linux.txt

    1,a

    2,b

    3,c

    4,d

    5,e

    2)按字符串查询

    [root@redhat~]#   sed  -n  ' /cto/p '  linux.txt

    2,b,cto

    [root@redhat~]#   sed  -n  ' /cto/,/cfo/p '  linux.txt

    2,b,cto

    3,c,coo

    4,d,cfo

    3)混合查询

    [root@redhat~]#   sed  -n  ' 2,/cfo/p '  linux.txt

    2,b,cto

    3,c,coo

    4,d,cfo

    [root@redhat~]#   sed  -n  ' /e/,2p '  linux.txt

    5,e,cio

    #-->特殊情况,前两行没有匹配到e,就向后匹配,如果匹配到e就打印此行

  • 相关阅读:
    【二分】Pair of Topics
    【Windows】制作登录界面
    【Windows】制作文本框
    【windows】制作幸运“Tiger”机
    【python】函数
    SPOJ 3267 DQUERY
    CF 570D Tree Requests
    UVa 11809 Floating-Point Numbers
    Luogu P5098 Cave Cows 3
    GHOJ 428 未出现的子串
  • 原文地址:https://www.cnblogs.com/axzq/p/9595310.html
Copyright © 2020-2023  润新知