Linux文本处理三剑客之 sed流编辑器

sed (Stream Editor) 流编辑器

sed工作模式

  依次从文件中读取一行,不编辑源文件;符合要求的行(能被模式匹配到的行)送到“模式空间 (pattern space)”执行编辑或其他操作,而后把处理过的结果输出至标准输出(屏幕);不符合要求的行(不能被模式所匹配到的行)也输出至标准输出
  不管能否被“模式空间”所匹配到(除非遇到”d’命令),都会先输出至屏幕(标准输出)

Linux文本处理三剑客之 sed流编辑器

语法:sed [OPTION]... 'script' FILE...
   sed [OPTION]... 'COMMAND1[;COMMAND2]…' FILE…
   sed [OPTION]... 'ADDRESS_COMMAND' FILE…
   sed [OPTION]...'/PATTERN/COMMAND' FILE…
选项:
   -n:静默模式;不输出模式空间中的(原有)内容到屏幕(标准输出)
   -i:直接修改原文件
   -e {SCRIPTS|COMMAND}:指定多个sed脚本(多点编辑)或编辑命令
   -f /PATH/TO/SED_SCRIPT_FILE:可以把sed的编辑命令放在一个文件当中;从指定文件中读取编辑脚本(每行一个编辑命令)
   -r:使用扩展正则表达式

sed脚本 (script)

   sed脚本指的是:地址定界+编辑命令;sed脚本中,不能有引号(' ' " ")

地址定界 (ADDRESS)

  • 不给地址(空地址):对全文(每一行)进行处理
  • 单地址
     10
     10,
  • 地址范围
     开始行,结束行(1,100)
     $:最后一行
     n!:除了第n行外的所有行
     '^$:空行
     开始行,+结束行(10,+2)
     从开始行开始,向后的2行
  • 模式
     / PATTERN /:被此模式所能匹配到的每一行
     /^PATTERN/:以指定模式开头的行
     开始行,/ PATTERN /:从指定的行开始到第一次被模式匹配到的行,之间的所有行
     / PATTERN 1/,/ PATTERN 2/:从第一个符合模式1的行开始,到第二个符合模式2的行结束,中间的所有行
  • ~:步进
     显示所有奇数行:1~2
     显示所有偶数行:2~2
    正则表达式元字符:https://blog.51cto.com/zhangdaifu/1973716

sed的子命令 (COMMAND)

 多个子命令(COMMAND)用分号“;”分隔

编辑命令

  d:删除符合条件的行;使用此编辑命令时需禁用’-n’选项(可以和地址定界,模式一同使用)
  p:显示符合条件(地址定界中模式空间)的行
  a \TEXT:在匹配到的行后(下),追加一个或一些文本(新行);支持使用’-n’实现多行追加
  i \TEXT:在匹配到的行前(上),插入一个或一些文本(新行);支持使用’-n’实现多行插入
  c \ TEXT:把匹配到的行替换成此处指定的文本在追加、替换、插入的时候,可以用“\n”换行

# sed '2a# New Line' /etc/fstab
# sed '/[[:space:]]/a \ 1 \n 2' /etc/fstab
# sed '2a# New Line 1\n# New Line 2' /etc/fstab
# sed '/^[[:upper:]]/i \New' /etc/fstab
# sed '/^[[:upper:]]/c \UUID' /etc/fstab

注意:sed的地址定界和编辑命令是不可分开的
  r /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行(下)后面;用于实现文件合并
  w /PATH/TO/SOMEFILE:保存(覆盖)模式空间匹配到的行至指定的文件中;另存为操作
  =:为模式匹配到的行的行的前(上)面显示行号
  !:条件取反;放在模式后面编辑命令之前(地址定界!编辑命令);对地址定界取反;除了对匹配到行以外的其他行,做出编辑操作
  SOMEFILE:某文件

# sed -n '/^[^#]/w /tmp/fstab.new' /etc/fstab
# sed "/^[^#]/w $(mktemp /tmp/XXX)" /etc/fstab
# sed '3r /etc/issue' /etc/fstab
# sed '/^UUID/=' /etc/fstab

注意:如果想在一个处理当中,执行多条子命令,则使用“;”隔开

查找替换

语法格式:s[/地址定界]/查找条件/替换内容/[修饰符]

注意:除“/”外,sed还支持使用其他字符作为修饰符“@”“#”“|”__

  s:查找条件可以指“模式”
   查找条件可以使用模式,但要替换的内容不行
  y:逐个字符进行替换;和“s”不同的是,y将字符集替换成与之完全匹配的字符集(和tr命令一样,但不支持正则表达式)
   # echo "ABC" | sed 'y/ABC/abc/'
   # sed 'y@UUID@uuid@' /etc/fstab

修饰符(替换标记)

  [N]g (global):第N处替换/行内全局替换; 默认替换一个
  i (ignore-case):匹配时,忽略字符大小写
  &:引用模式匹配到的整个串
  p:显示替换成功的行
  w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中

练习

1:删除/boot/grub/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符

  # sed 's@^[[:space:]]*@@g' /boot/grub2/grub.cfg

2:删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面的所有空白字符

  # sed 's@^#[[:space:]]*@@g' /etc/fstab

3:输出一个绝对路径给sed命令,取出其目录,其行为类似于dirname

  # echo /home/zhangdaifu | sed 's@[^/]+/\?$@@'
  # echo /home/zhangdaifu/ | sed -r 's@[^/]+/?$@@'

sed命令示例

  大部分以/etc/fstab文件为例

显示文件中所有内容

  sed '' FILE
  sed -n 'p' FILE

将文件复制一份

  sed 'w /tmp/fstab' /etc/fstab

不显示以“/”开头的行

   sed '/^\//d' /etc/fstab

不显示以“#”开头的行

  sed '/^#/d' FILE
  sed -n '/^[^#]/p' FILE
  sed -n '/^#/!p' FILE

显示从第2行到第1个以“#”开头的行

  sed '2,/^#/d' /etc/fstab

在所有以“#”开头的行后,追加一句话

  sed '/^#/a \Hello' /etc/fstab

在所有以大写字母开头的行后,追加一句话

  sed '/^[[:upper:]]/a \new_line' /etc/fstab

在UUID开头的行后插入/etc/issue文件中的内容

  sed '/^UUID/r/\/etc/issue' /etc/fstab

将“#”开头的行保存到/tmp/test文件中

  sed -n '/^#/w /tmp/test' /etc/fstab

显示以“#”开头的行,并显示行号

  sed '/^#/=' /etc/fstab

将#开头的行删除

  sed '/^#/d' /etc/fstab

将#开头的行的#和空白行删除

  sed -e 's/^#//' -e '/^$/d' /etc/fstab

将文件中除了#开头的行,其余全部删除

  sed '/^#/!d' /etc/fstab

将文件中所有行的行首都加入#号

  sed 's/^/#/' /etc/fstab

给UUID所在行的UUID字符串加上双引号

  sed 's/UUID/"&"/g' /etc/fstab

给UUID所在行加上双引号

  sed -n 's@UUID.*@"&"@p' /etc/fstab

删除UUID所在行

  sed -e 's/^#[[:space:]]*//' -e '/^UUID/d' /etc/fstab

高级编辑命令

sed的保持空间

  sed的所有编辑操作都在“模式空间”中进行编辑操作,编辑完之后如果还没有编辑结束,可以将数据放置“操持空间 (HOLD SPACE)”中,而后再处理下一行,处理完之后可以把“操持空间”当中的数据拿回再次进行处理

模式空间 == 车间
操持空间 == 仓库

  h:把模式空间中的内容覆盖至保持空间中
  H:把模式空间中的内容追加至保持空间中
  g:从保持空间取出数据覆盖至模式空间
  G:从保持空间取出数据追加至模式空间
  x:把模式空间中的内容与保持空间中的内容进行互换
  n:覆盖读取匹配到的行的下一行至模式空间中
  N:追加读取匹配到的行的下一行至模式空间中
  d:删除模式空间中的行
  D:删除多行模式空间中的所有行

sed调用shell变量

sed “$变量”
  # sed "s@\/bin\/sh@$SHELL@" /etc/shells

sed高级用法

显示奇数行

  # sed 'n;d' FILE
  # sed -n '1~2p' FILE

显示偶数行

  # sed -n 'n;p' FILE
  # sed '1~2d' FILE

删除最后一行

  # sed -n 'N;p' FILE

取出最后一行

  # sed '$!d' FILE
  # sed -n '$p' FILE

取出最后两行

  # sed '$!N;$!D' FILE

显示包含数字的行

  # sed 'N;s/\n/\t/' FILE

在原有的每行后方添加一个空白行

  # sed 'G' FILE

删除原有的所有空白行,而后为所有的非空白行后添加一个空白行(将多个空白行合并为一个,然后在每行后方添加一个空白行)

  # sed '/^$/d;G' FILE
  除了第一行:# sed '1!G' FILE

sed可以模拟一些命令

 取出文件头五行(相当于head -5)

  # sed '5 q' FILE

 把文件创建一个副本(相当于cp命令)

  # sed -n 'w /PATH/TO/NEW_FILE' FILE

 统计文件中的行数(相当于wc -l)

  # sed -n '$ =' FILE

 逆向显示文件内容(相当于tac)

  # sed '1!G;h;$!d' FILE
  # sed -n '1!G;h;$p' FILE

更多:https://www.yiibai.com/sed/sed_useful_recipes.html

-------------------------------------------------------------------The End-----------------------------------------------------------------
--------------------------------------------------------------------Thank-------------------------------------------------------------------
------------------------------------------------------------------ by: ZDF -----------------------------------------------------------------
blog:http://zhangdaifu.blog.51cto.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章