sed 快速参考

这里的内容大部份摘自 UNIX超级工具。

sed的操作方式如下

每行输入都会被复制到模式空间中

可以直接在命令行中输入编辑命令(多个命令请加-e选项)。 也可以用-f选项来从脚本文件里得到编辑命令。所有的编辑命令都会按照文本的 输入顺序作用于各行。

编辑命令会作用于所有的行(全局),除非用行寻址限定了命令所作用的行。

如果一个命令更改了输入,那么后续的命令地址就会作用于模式空间中当前行, 而不是原始输入行。

原始输入文件不会被更改,编辑命令修改的是原始文件输入行的副本。 除非使用-n选项,否则该副本会被 发送到标准输出。你可能需要重定向到一个 文件。(但是别重定向到同一个文件,那样你的文件就被清空了!)

sed命令的语法

sed命令有通用的格式:

[address][,address][!]command[arguments]

sed命令一般包含地址address和编辑命令command. command包括单个字母或符号.arguments包括用于b或t的标签, 用于r或w的文件名、用于s的替换标志."[something]"表示可选项.

在sed中,大括号({})用于把一个地址嵌套在另一个地址内空,或在相同的地址 上应用多个命令.可以用多行分隔命令,或者用";".

模式寻址

一个sed命令可以指定0-2个地址. 这个地址可以是行号、符号$(表示最后一行)或者是包含在斜杠内的正则表达 式. 除此之外,\n可以用来匹配模式空间中换行符(由N命令产生),但是不能 匹配模式空间末尾的换行符.

sed命令概要

# 在sed脚本中开始一个注释行.如果第一个注释行确切为#n,说明sed设置了命令行选项-n
: :label 给脚本的一行加上标签,以便使用命令b或t进行转移控制.参数label最多可包含7个字符.
= [address]= 把每一行的行号写到标准输出.
a [address]a\\\\n text 在匹配行后面添加文本.text可以包含多行,但换行符需要用\\隐藏起来.
b [address1][,address2]b[label] 无条件转移到标签,默认转到脚本末尾.
c [address1][,address2]c\\\\n text 用文本替换地址所选择的行.如果指定了行的范围,那么所有的行会被作为一组被单个的文本替换.同a命令,文本的换行符需要隐藏起来
d [address1][,address2]d 删去匹配的行,因而不会发送到标准输出
D [address1][,address2]D 删去由命令N所创建的模式空间中的多行文本的第一部分(一起到插入的换行符为止),并脚本中的第一个命令恢复编辑.如果该命令清空了模式空间,那么就会读取一行新的输入,如同执行了命令d一样.
g [address1][,address2]g 把保留空间中内容粘贴到模式空间中,清除模式空间中原来的内容.
G [address1][,address2]G 同g功能相同,但是是追加到模式空间中.
h [address1][,address2]h 把模式空间中内容复制到保留空间中.
H [address1][,address2]H 把模式空间中内容追加到保留空间中.
i [address]i\\\\n text 在先前插入文本,参考a.
n [address1][,address2]n 把下一行读入到模式空间中.当前行发送到标准输出,下一行将成为当前行.控制将转移给n后面的所跟的命令,而不是回到脚本的开始处.
N [address1][,address2]N 把下一个输入行添加到模式空间的内容之后;这现行文本用一个插入的换行符分开.(该命令允许跨越两行进行模式匹配.)如果用\\n来匹插入的换行符,那么可以跨越多行进行模式匹配.
p [address1][,address2]p 打印行,除非使用了命令行选项-n,否则这命令将导致输出相同的行.另外它常用于那些用于改变流控制的命令之前,并可能输出当前行.
P [address1][,address2]P 打印由命令N创建的多行模式的第一部分(一直到插入的换行符为止).如果没有应用命令N, 那么该命令的作用与p相同.
q [address]q 退出
r [address]r file 读取文件内容,并把它添加到模式空间的内容后面.命令r和文件之间必须刚好一个空格.
s [address1][,address2]s /pattern/replacement/[flags] 替换.flags可以为n(数字,指匹配的第n个),g,p, w file.
t [address1][,address2]t[label] 测试是否在寻址到的行上完成了任何替换,如果是将控制转移到标签,默认标签为脚本尾.
w [address1][,address2]w file 把模式空间中内容添加到文件中.遇到此命令即发生动作.w与file之间必须刚好一个空格.一次最多能打开10个文件.如果文件不存在,会创建之.存在, 每次执行该命令时,它都会被重写一次.但多个直接输出到同一个文件的命令会在文件末尾进行追加.
x [address1][,address2]x 交换保留空间与模式空间中内容.
y [address1][,address2]y/abc/xyz/ 转换字符.a->x,b->y,c->z.

Example

#!/bin/sh
# cgrep - 使用sed的多行上下文grep
# 用法:cgrep [-context] pattern [file ...]

n=3
case $1 in -[1-9]*)
n=`expr 1-"$1"`
shift
esac
re=$(1?);shift

sed -n "
1b start
: top
\~$re~{
  h;n;p;H;g
  b endif
}
  N
  : start
  \~$re~{ = ; p;}
: endif
$n,\$D
b top
" "$@"

No comments: