[shell] sed 用法

a\ 表示在当前行后添加一行或多行。多行时 除最后一行外,每行末尾需用“\”续行

sed –i‘/super/a\HHHH  a.b.c;’ file_name

sed -i 's/HHHH//g' file_name;

super的下一行插入HHHH…等内容,由于插入的内容开头不能是空格,所以先插入HHHH(可以是其他任意字符)和空格,然后再删掉HHHH,这样就可以实现在新的一行开头插入空格;

 

c\ 表示用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行;

 

i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行;

 

d 表示删除行

sed '2,5d' file_name #删除第二到第五行;

 

替换:

sed 's/要被替换的字符串/新的字符串/g'

如果没有g标记,则只有每行第一个匹配的字符被替换

sed -i's/被替换的内容/要替换成的内容/' file  #  -i 直接修改并保存

 

sed -n's/^test/mytest/p' example

(-n)选项和p标志一起使用表示只打印那些发生替换的。也就是说,如果某一行开头的test被替换成mytest,就打印它。

 

sed 's/^192.168.0.1/&localhost/'example

&符号表示替换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成192.168.0.1localhost。

 

sed -n 's//(love/)able//1rs/p' example

love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来

 

sed -n '5,/^test/p' example  #打印从第五行开始到第一个包含以test开始的行之间的所有行。

 

sed -e '1,5d' -e 's/test/check/' example

(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

 

sed -n '/test/file' example

-----在example中所有包含test的行都被写入file里

 

下一个:n命令 

sed '/test/{ n; s/aa/bb/; }' example

如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。

 


 

cat filename | sed –n ‘/1024/p’    #打印出含有字串”1024”的行

sed /^$/d filename                  #可以删除文件中的空行。

sed /^[[:space:]]*$/d filename    #可以删除内容为多个空格/tab组成的行。


sed支持反向匹配
----------------------------------------------
sed -n '/bsp/!p' file  #匹配不包含bsp的行


正则表达式元字符:

元字符 功能 示例
 ^ 行首定位符 /^my/  匹配所有以my开头的行
 $ 行尾定位符 /my$/  匹配所有以my结尾的行
 . 匹配除换行符以外的单个字符 /m..y/  匹配包含字母m,后跟两个任意字符,再跟字母y的行
 * 匹配零个或多个前导字符 /my*/  匹配包含字母m,后跟零个或多个y字母的行
 [] 匹配指定字符组内的任一字符 /[Mm]y/  匹配包含My或my的行
 [^] 匹配不在指定字符组内的任一字符 /[^Mm]y/  匹配包含y,但y之前的那个字符不是M或m的行
  保存已匹配的字符 1,20s/self/\1r/  标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。
 & 保存查找串以便在替换串中引用 s/my/**&**/  符号&代表查找串。my将被替换为**my**
 \< 词首定位符 /\<my/  匹配包含以my开头的单词的行
 \> 词尾定位符 /my\>/  匹配包含以my结尾的单词的行
 x\{m\} 连续m个x /9\{5\}/ 匹配包含连续5个9的行
 x\{m,\} 至少m个x /9\{5,\}/  匹配包含至少连续5个9的行
 x\{m,n\} 至少m个,但不超过n个x /9\{5,7\}/  匹配包含连续5到7个9的行

-r, --regexp-extended  在脚本中使用扩展正则表达式

sed -r 's/^(.)(.)/\2/g' passwd                                      #删除文件每行的第二个字符

sed -r 's/(.)$//g'                                                         #删除文件每行的最后一个字符

sed -r 's/^([a-Z])([^0-9][^a-Z])(a-Z)/\1\2/g' passwd    #删除文件每行的第二个单词

-----------------------------------------------------------------------------------------------------------------------------------

模式空间 和 保持空间

-----------------------------------------------------------------------------------------------------

保持和获取:h命令和G命令

h:模式空间 ---->    保持空间(覆盖)
H:模式空间 --->>  保持空间(追加)
x:模式空间 <--->   保持空间(交换)
g:保持空间 ---->    模式空间(覆盖)
G:保持空间 --->>   模式空间(追加)

所谓模式空间:当前按指定模式匹配到的行的内容;比如 sed -n '/test/p' a.log,其中含有test的行就被复制到模式空间

保持空间:可以理解为把按指定模式把匹配到的行暂时缓存的一个空间;


sed -e '/test/H' -e '$G’ example

任何包含test的行都被复制并追加到该文件的末尾($表示文件最后一行)。

 

互换:x命令 
 sed -e '/test/h' -e '/check/x' example    #
把包含test与check的行互换。

        >>cat a.log

          test1

          test2 

         check1 

         check2

        >> sed -e '/test/h' -e '/check/x' a.log

           test1    # 把test1存入保持空间

           test2    # 由于是h ,所以test2 存入保持空间,并把上次存入的test1覆盖

           test2    # 把保持空间的内容(test2)输出,再把check1存到保持空间

           check1 # 把保持空间的内容(check1)输出

         

   >> sed -e '/test/H' -e '/check/x' a.log

           test1    # 把test1存入保持空间

           test2    # 由于是H ,所以test2 追加存入保持空间,此时保持空间包含test1和test2和空行初始时,保持空间包含一个空行)

                        #由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出

           test1    # 由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出

           test2    # 由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出,把check1存入保持空间

           check1 # 把保持空间的内容(check1)输出


     >>sed '1h;2H;3G'  #把第一行和第二行复制到第三行后面

         

           test1    

           test2    

           check1   

           test1  

           test2    

           check2 

    >>sed '1,2H;3G'  #把第一行和第二行复制到第三行后面   

            test1    

           test2    

           check1   

                        #会打印一行空行,为了规避空行使用上面的写法,先存入数据到保持空间,覆盖掉初始的空行

           test1  

           test2    

           check2 


sed 反向输出

>> seq 6
1
2
3
4
5
6
>> seq 6 | sed '1!G; h; $!d'  
6
5
4
3
2
1

分析:

第一行的时候
1!G        在处理 第一行 的时候不把缓冲内容(保持空间) 追加 到当前处理行的末尾(因为你处理第一行的时候,缓冲为空)
h           这个时候把第一行的内容(1)放到缓冲区
$!d        因为不是最后一行,所以删除,不打印出来

第二行的时候
1!G        因为是第二行,所以1!G成立,则把上一次(第一行)保存的缓冲区内容(1)放到当前行(2)的末尾,第二行变成了(21)
h           这个时候把第二行的内容(21)放到缓冲区
$!d        因为不是最后一行,所以删除,不打印出来

第三行的时候
1!G        因为是第三行,所以1!G成立,则把上一次(第二行)保存的缓冲区内容(21)放到当前行(3)的末尾,第二行变成了(321)
h           这个时候把第三行的内容(321)放到缓冲区
$!d        因为不是最后一行,所以删除,不打印出来

....
....

第六行的时候
1!G        因为是第六行,所以1!G成立,则把上一次(第5行)保存的缓冲区内容(54321)放到当前行(6)的末尾,第六行变成了(654321)
h           这个时候把第六行的内容(654321)放到缓冲区
$!d        因为是最后一行,所以不删除,打印出第六行内容 654321

电话号码作为表达式的输入,要求若号码不是以021为前缀,则必须把整个号码转换为字符串bar
   

echo 02188888888 | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_021/021/' | sed 's/^_t_.*$/bar/'

这里只是用Linux命令来与管道演示一下,命令执行的结果将输出02188888888(保持号码不变),步骤说明:

1)第一个表达式 sed 's/^/(.*/)$/_t_/1/'  意思是“在号码前面加一个特殊前缀_t_”,号码02188888888被处理后,第一个表达式将输出 _t_02188888888 。

2)第二个表达式 sed 's/^_t_021/021/'  意思是“若输入的字符串前缀为_t_021,则转化该前缀为021”,此处_t_02188888888 又变回了 02188888888。

3)第三个表达式 sed 's/^_t_.*$/bar/'  意思是“若输入的字符串前缀为_t_,则把整个字符串替换成bar”,此处输入为02188888888,所以本表达式不起作用,最终输出还是02188888888。(即允许拨打该号码)

再看看若输入的是一个非021前缀的号码:

echo 05788888888 | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_021/021/' | sed 's/^_t_.*$/bar/'

1)第一个表达式 sed 's/^/(.*/)$/_t_/1/'  处理结果在号码05788888888前加了前缀:_t_05788888888 。

2)第二个表达式 sed 's/^_t_021/021/'  发现字符串_t_05788888888 不是以_t_021为前缀,所以它将不做任何处理,输出的结果还是_t_05788888888 。

3)第三个表达式 sed 's/^_t_.*$/bar/'  发现字符串前缀为_t_,则把整个字符串替换成了bar


上述表达式只适用于“替换前缀不为XX的字符串”,若要匹配的标识在字符串中间怎么办?

 比如,如何实现“请替换不含hero的整个字符串为bar”的要求。

echo 'I am hero yeah' | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_/(.*/)hero//1hero/' | sed 's/^_t_.*$/bar/'

将输出 'I am hero yeah' ,而输入其它字符串,如:

echo 'He is not' | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_/(.*/)hero//1hero/' | sed 's/^_t_.*$/bar/'

将输出 'bar'。


应用举例


1. 删除文件每行的第一个字符。
    sed -n 's/^.//gp' /etc/passwd
    sed -nr 's/(.)(.*)/\2/p' /etc/passwd

2. 删除文件每行的第二个字符。

    sed -nr 's/(.)(.)(.*)/\1\3/p' /etc/passwd

3. 删除文件每行的最后一个字符。

     sed -nr 's/.$//p' /etc/passwd

     sed -nr 's/(.*)(.)/\1/p' /etc/passwd

4. 删除文件每行的倒数第二个字符。

     sed -nr 's/(.*)(.)(.)/\1\3/p' /etc/a.log

5. 删除文件每行的第二个单词。

      sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\2\3\5/p' /etc/a.log

6. 删除文件每行的倒数第二个单词。

    sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4\5\6/p' /a.log

7. 删除文件每行的最后一个单词。

     sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4/p' ./a.log

8. 交换每行的第一个字符和第二个字符。

     sed -nr 's/(.)(.)(.*)/\2\1\3/p' /etc/passwd

9. 交换每行的第一个单词和第二个单词。

     sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' ./a.log

10. 交换每行的第一个单词和最后一个单词。

       sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' ./a.log

11. 删除一个文件中所有的数字

      sed 's/[0-9]*//g' /etc/passwd

12. 删除每行开头的所有空格。

      sed -n 's/^\ *//p' ./a.log

      sed -nr 's/( *)(.*)/\2/p'  ./a.log

13. 用制表符替换文件中出现的所有空格。

      sed -n 's/\ /\t/gp' ./a.log

14. 把所有大写字母用括号()括起来。

     sed -nr 's/([A-Z])/(&)/gp' ./test

     sed -n 's/[A-Z]/(&)/gp' ./test

15. 打印每行3次

      sed 'p;p' pass

16. 隔行删除

      sed -n '1~2p' ./a.log #删除奇数行
      sed '1~2!d' ./a.log #删除偶数行

17. 把文件从第22行到第33行 复制到第44行后面

      sed '1,21h;22h;23,33H;44G' ./a.log

18. 把文件从第22行到第33行 移动到第44行后面

     sed '22{h;d};23,33{H;d};44G' pass

19. 只显示每行的第一个单词

      sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)(.*)/\2/p' /etc/passwd

20. 打印每行的第一个单词和第三个单词

       sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\2--\4/p' /etc/passwd


21. 将格式为 mm/yy/dd 的日期格式换成 mm;yy;dd

       date +%m/%Y/%d |sed -n 's#/#;#gp'
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值