Sed 命令详解
之前在《glob 及 grep 正则表达式简介》里面介绍过
glob
, grep
, egrep
和 fgrep
这些文本过滤器。下面来说说 sed
流编辑器。
简介
Sed(Stream EDitor),流编辑器,行编辑工具,默认不直接编辑文件。每次读出一行数据放入内存,在内存中的模式空间( pattern space )中进行匹配,将匹配到的行进行修改,之后放入保存空间,然后再输出到标准输出;未匹配到的行直接输出到标准输出。命令格式
sed [OPTION]... 'script' [input-file] ...
# script 为地址定界和编辑命令(的集合)
常用选项(OPTION)
-n
:不输出模式空间中的内容至屏幕; -e script, --expression=script
:多点编辑; -f /PATH/TO/SED_SCRIPT_FILE
:将多个编辑命令写入一个文件,再统一读取执行; -r, --regexp-extended
:支持使用扩展正则表达式; -i[SUFFIX], --in-place[=SUFFIX]
:直接编辑源文件;
地址定界(script)
地址定界大致分为以下几种模式,用于编辑命令前:''
:为空时表示对全文进行处理; n
:指定为第 n 行; /pattern/
:被此模式匹配到的每一行; n,m
:从第 n 行开始,到第 m 行结束; n,+m
:从第 n 行开始,递增 m 行结束; /pattern1/,/pattern2/
:从 pattern1 第一次匹配到的行开始,到 pattern2 第一次匹配到的行结束; 1~2
:从第 1 行开始,每隔 2 行进行匹配,即 1 3 5 7...;
编辑命令(script)
用于地址定界后,若地址定界为空,则默认对全文进行操作。d
:删除; p
:显示模式空间中的内容; a \text
:在行后面追加文本「text」,支持使用\n实现多行追加; i \text
:在行前面插入文本「text」,支持使用\n实现多行插入; c \text
:把匹配到的行替换为此处指定的文本「text」; w /PATH/TO/SOMEFILE
:保存模式空间匹配到的行至指定的文件中; r /PATH/FROM/SOMEFILE
:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并; =
:为模式匹配到的行打印行号; !
:条件取反,放在编辑命令前,表示不执行; s///
:查找替换,其分隔符可自行指定,常用的有s@@@, s###等; 其中,查找替换 s///
有如下几个操作: g
:全局替换; w /PATH/TO/SOMEFILE
:将替换成功的结果保存至指定文件中; p
:显示替换成功的行; 注意:除非使用 -i
选项,否则 sed 默认都将只输出更改后的内容,而不会更改源文件。
示例
1) 输出/etc/fstab
文件内容,并在第三行插入 new line
:
sed '3i \new line' /etc/fstab
2) 输出 /etc/fstab
文件内容,并在 UUID
开头的行后面插入 new line
:
sed '/^UUID/a \new line' /etc/fstab
3) 查找 /etc/fstab
文件中 UUID
开头的行,并输出到 /tmp/fstab_new
中:
sed '/^UUID/w /tmp/fstab_new' /etc/fstab
4) 输出 /boot/grub/grub2.cfg
文件内容,并删除所有以空白字符开头的行的行首的所有空白字符:
sed 's@^[[:space:]]\+@@' /etc/grub2.cfg
5) 输出 /etc/fstab
文件内容,并删除所有以 #
开头的行的行首的 #
号及 #
后面的所有空白字符:
sed 's@^#[[:space:]]*@@' /etc/fstab
6) 输出一个绝对路径给 sed
命令,取出其目录,其行为类似于 dirname
:
echo "/var/log/messages/" | sed -r 's@[^/]+/?$@@'
高级编辑命令
h
:把模式空间中的内容覆盖至保持空间中; H
:把模式空间中的内容追加至保持空间中; g
:把保持空间中的内容覆盖至模式空间中; G
:把保持空间中的内容追加至模式空间中; x
:把模式空间中的内容与保持空间中的内容互换; n
:覆盖读取匹配到的行的下一行至模式空间中; N
:追加读取匹配到的行的下一行至模式空间中; d
:删除模式空间中的行; D
:删除多行模式空间中的所有行;
示例
sed -n 'n;p' FILE # 显示偶数行;
sed '1!G;h;$!d' FILE # 逆序显示文件的内容;
sed '$!d' FILE # 取出最后一行;
sed '$!N;$!D' FILE # 取出文件后两行;
sed '/^$/d;G' FILE # 删除原有的所有空白行,而后为所有的非空白行后添加一个空白行;
sed 'n;d' FILE # 显示奇数行;
sed 'G' FILE # 在原有的每行后方添加一个空白行;