欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

文本处理三剑客之 sed

程序员文章站 2023-02-26 13:33:30
sed:文本流编辑器 主要是对文件的快速增删改查,查询功能中最常用的是过滤,取行 sed [选项] [sed内置命令字符] [输入文件] Options: -n:取消默认的sed输出,常与sed内置命令p连用 -e:直接在命令行界面进行sed动作编辑,多点编辑 -r:使用扩展的正则表达式 -i:直接 ......

sed:文本流编辑器

  主要是对文件的快速增删改查,查询功能中最常用的是过滤,取行

  sed [选项] [sed内置命令字符] [输入文件]

  文本处理三剑客之 sed

 

 

  options:

    -n:取消默认的sed输出,常与sed内置命令p连用

sed -n '/要过滤的内容/或者行号p'

    -e:直接在命令行界面进行sed动作编辑,多点编辑
    -r:使用扩展的正则表达式
    -i:直接修改读取的文件内容,而不是由屏幕输出。若是不加此参数,就只是修改内存中的数据,不影响磁盘中的数据

  script:

    地址定界:
      1、不给地址,对全文进行处理
      2、单地址,
      #:指定的行
      /pattern/:被此处模式所能够匹配到的每一行

    地址范围:
      #,#:从#到#之间的行,包括##

      #,+#:从#行到#+#行

      /pat1/,/pat2/:匹配第一次被模式一和第一次被模式二匹配的行之间的行,贪婪模式!!!
      #,/par1/:第#行到第一次被part1匹配的行

    编辑命令:
      d:删除模式空间匹配的行

sed '3d' file.txt # 数字表示行号
sed '3,4d' file.txt # 3-4行删除

      p:显示模式空间中的内容

sed -n '2p' file.txt  # 匹配第二行内容,如果不加-n,会将匹配的内容输出到屏幕两次
sed -n '2p;4p' person.txt  2和4行
sed -n '/xiaolizi1/p;/xiaolizi2/p' person.txt 

      a[\]text:在指定行的后面追加文本,可使用\n实现多行追加

# 在第二行后追加内容
   sed '2a 要追加的内容' file.txt
# 追加多行内容
  sed '2a 要追加的内容\n要追加的内容' file.txt
sed  '$a 106,xiaolizi1\n107,xiaolizi2' person.txt  # 在最后一行追加两行内容 $表示结尾

      i[\]text:在指定行的前面追加文本
      c[\]text:替换行为单行或多行文本
      w /path/somefile:保存模式空间匹配的行到指定文件
      r /path/somefile:读取指定的文件的文本至模式空间匹配到的行的行后
      =:为模式空间中的行打印行号
      !: 对模式空间匹配的行取反处理

    查找替换:
      s///:支持使用其他分隔符:s@@@,s### ...

sed 's#替换前的内容#替换后的内容#g' file.txt  # g表示整个文本内容,也就是全局替换,如果不添加,只会替换第一个匹配到的内容

# 关于反向引用
  

[root@oldgirl ~]# #echo 123456 ==》 <123456>  # 转换成此类格式的 \1表示引用前面第一个括号内的内容
[root@oldgirl ~]# echo 123456|sed -r 's#(.*)#<\1>#g'
<123456>
[root@oldgirl ~]# #echo 123456 ==》<1><2><3><4><5><6>
[root@oldgirl ~]# echo 123456|sed -r 's#([1-6])#<\1>#g'
<1><2><3><4><5><6>
[root@oldgirl ~]# echo 123456|sed -r 's#(.)#<\1>#g'
<1><2><3><4><5><6>
[root@oldgirl ~]# echo 123456|sed -r 's#.#<&>#g'
<1><2><3><4><5><6>
[root@oldgirl ~]# echo 123456|sed -r 's#.*#<&>#g'
<123456>

 

# 举个栗子

# 需求将oldboy*.jpg图片变为avi扩展名文件
# 第一个里程:找出要替换的文件信息
[root@oldgirl ~]# ls oldboy*.jpg
oldboy01.jpg oldboy03.jpg oldboy05.jpg oldboy07.jpg oldboy09.jpg
oldboy02.jpg oldboy04.jpg oldboy06.jpg oldboy08.jpg oldboy10.jpg
[root@oldgirl ~]# ls oldboy*.jpg|sed 's#.*#&#g'
oldboy01.jpg
oldboy02.jpg
oldboy03.jpg
oldboy04.jpg
oldboy05.jpg
oldboy06.jpg
oldboy07.jpg
oldboy08.jpg
oldboy09.jpg
oldboy10.jpg
#  第二个里程:拼凑批量修改文件的命令
[root@oldgirl ~]# ls oldboy*.jpg|sed 's#.*.jpg#&#g'
oldboy01.jpg
oldboy02.jpg
oldboy03.jpg
oldboy04.jpg
oldboy05.jpg
oldboy06.jpg
oldboy07.jpg
oldboy08.jpg
oldboy09.jpg
oldboy10.jpg

[root@oldgirl ~]# ls oldboy*.jpg|sed -r 's#(.*)jpg#\1#g'
oldboy01.
oldboy02.
oldboy03.
oldboy04.
oldboy05.
oldboy06.
oldboy07.
oldboy08.
oldboy09.
oldboy10.
[root@oldgirl ~]# ls oldboy*.jpg|sed -r 's#(.*)jpg#mv \1jpg#g'
mv oldboy01.jpg
mv oldboy02.jpg
mv oldboy03.jpg
mv oldboy04.jpg
mv oldboy05.jpg
mv oldboy06.jpg
mv oldboy07.jpg
mv oldboy08.jpg
mv oldboy09.jpg
mv oldboy10.jpg
[root@oldgirl ~]# ls oldboy*.jpg|sed -r 's#(.*)jpg#mv \1jpg \1avi#g'
mv oldboy01.jpg oldboy01.avi
mv oldboy02.jpg oldboy02.avi
mv oldboy03.jpg oldboy03.avi
mv oldboy04.jpg oldboy04.avi
mv oldboy05.jpg oldboy05.avi
mv oldboy06.jpg oldboy06.avi
mv oldboy07.jpg oldboy07.avi
mv oldboy08.jpg oldboy08.avi
mv oldboy09.jpg oldboy09.avi
mv oldboy10.jpg oldboy10.avi

# 第三里程碑:将命令输出的信息,进行执行
[root@oldgirl ~]# ls oldboy*.jpg|sed -r 's#(.*)jpg#mv \1jpg \1avi#g'|bash
[root@oldgirl ~]# ls oldboy*.avi
oldboy01.avi oldboy03.avi oldboy05.avi oldboy07.avi oldboy09.avi
oldboy02.avi oldboy04.avi oldboy06.avi oldboy08.avi oldboy10.avi

  

# 以上只是一个需求,为了演示反向引用,如果批量重命名的话,使用rename即可

    替换标记:

      g:行内全局替换
      p:显示替换成功的行
      w file:将替换成功的行保存至文件中

+ g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除

+ g:[address[,address]]g 将hold space中的内容append到pattern space\n后

+ h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除

+ h:[address[,address]]h 将pattern space中的内容append到hold space\n后

+ d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中

+ d:[address[,address]]d 删除multiline pattern中的第一行,不读入下一行

ps:不论是使用g、g还是h、h,它们都是将hold space里面的内容“copy”到patt

h: 把模式空间中的内容覆盖至保持空间中
h:把模式空间中的内容追加至保持空间中
g: 从保持空间取出数据覆盖至模式空间
g:从保持空间取出内容追加至模式空间
x: 把模式空间中的内容与保持空间中的内容进行互换
n: 读取匹配到的行的下一行覆盖至模式空间
n:读取匹配到的行的下一行追加至模式空间
d: 删除模式空间中的行
d:删除当前模式空间开端至\n的内容(不再传至标准输 出),放弃之后的命令,但是对剩余模式空间重新执行sed