: label 建立脚本内指令互相参考的位置。
# 建立解
{ } 集合有相同位址参数的指令。
! 不执行函数参数。
= 打印内容行数( line number )。
a 添加使用者输入的资料。
b label 将执行的指令跳至由 : 建立的参考位置。
c 以使用者输入的资料取代资料。
d 删除pattern space的内容。
D 删除pattern space内第一个newline字母前的内容。
g 将内容从hold space拷贝到pattern space(覆盖)
G 将内容从hold space拷贝添加到pattern space
h 将内容从pattern space拷贝到hold space(覆盖)
H 将内容从pattern space拷贝添加到hold space
l 打印文件中的 nonprinting character 用 ASCII 码。
i 插入添加使用者输入的资料行。
n 读入下一行。
N 添加下一行到pattern space。
p 打印pattern space的内容。
P 打印pattern space内第一个newline字母前的内容。
q 跳出sed编辑。
r 读入文件内容。
s 替换字串。
t label 先执行一替换的编辑指令,如果替换成功则将编辑指令跳至 : label 处执行。
w 写内容到文件。
x 交换hold space与pattern space的内容。
y 转换(transform)字元。
虽然sed只有上面这些拥有基本编辑功能的函数,但由指令中位址参数和指令与指令间的配合,能使sed 完成大部份的编辑任务。
sed是一种面向字符流的编辑器。处理文件时,sed把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾,一次只处理文件中一行的拷贝。文件内容并没有改变,除非你使用重定向存储输出。
sed同时维护着模式空间(pattern space)和保持空间(hold space),可以将模式空间的内容复制到保持空间并在以后检索它们。
调用sed命令有两种形式
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
常用的options
-e command, --expression=command 允许多点编辑。
-n, --quiet, --silent 取消默认输出。
-f, --filer=script-file 引导sed脚本文件名
使用的基础command及示例
1、[address]s/pattern/replacement/flags ---substitution
用string替换正则表达式re。
以下的是替换标记flags
g表示行内全面替换。
p表示打印行。
w表示把行写入一个文件。
示例:sed -i 's/old/new/g' file GNU sed version 4.0.5以上带有-i选项
2、d [ address [,address ] ] d---delete
从模式空间(Pattern space)位置删除匹配行。
示例:
$sed '1d' quote.txt
It was an evening of splendid music and company.
Too bad the disco floor fell through at 23:00.
The local nurse Miss P.Neave was in attendance
$ sed '1,3d' quote.txt
The local nurse Miss P.Neave was in attendance.
$sed /^$/d 删除空行
3、追加 插入 更改
a ---append
在当前行后面加入一行文本。
i ---insert
在当前行上面插入文本。
c ---change
用新的文本改变本行的文本。它清除模式空间的内容,类似d命令的效果
append [line-address]a\
text
insert [line-address]i\
text
change [address]c\
text
4、l ---list
显示模式空间内容,将非打印的字符显示为两个数字的ascii码。
$ cat test/spchar
Here is a string of special characters: ^A ^B
^M ^G
$ sed -n -e "l" test/spchar
Here is a string of special characters: \01 \02
\15 \07
$ # test with GNU sed too
$ gsed -n -e "l" test/spchar
Here is a string of special characters: \01 \02
\r \a
5、y [address]y/abc/xyz/ ---Transform
按位置将abc中的每个字符转换成xyz中的
转换成大写
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
6、p ---print
打印模式空间的行。
=
打印被匹配行的行号。
q [line-address]q---quit
退出sed。
7、n [address]n ---next
输出模式空间内容,然后读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。不返回脚本顶端。
附录:sed正则表达式元字符集
^
锚定行的开始 如:/^sed/匹配所有以sed开头的行。
$
锚定行的结束 如:/sed$/匹配所有以sed结尾的行。
.
匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。
*
匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[]
匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^]
匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\)
保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
&
保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\<
锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\>
锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\}
重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
x\{m,\}
重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。
x\{m,n\}
重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。
sed基础二
sed的高级命令,按照《o’reilly sed and awk》分法,分成如下三组:(本文很多例子也出自这本书)
一 处理多行模式空间(N D P)
二 采用保持空间来保存模式空间的内容并使它可用于后续的命令(H h G g x)
三 使用分支和条件指令更改脚本的控制流(: b t)
sed脚本中,正常的控制流是:一行被读入模式空间并且用脚本的每个命令逐个地应用于那一行,当到达脚本的底部时,输出这一行并且清空模式空间,然后新行被读入模式空间,控制被转移到脚本的顶端。
在这里, 我们将改变脚本控制流,按照我们的预期来执行。
第一部分 N D P命令
N命令:
多行N命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。最初内容与新行直接用\n分隔,sed将它看作一个有很多嵌入行的整行。
小n命令区别在于它输出模式空间内容,然后读取新行,并不建立多行模式空间。
示例:
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
我们现在想要将"Owner and Operator Guide"换成"Installation Guide",但它出现在文件的两行上,
/Operator$/{
N
s/Owner and Operator\nGuide/Installation Guide/
}
避免产生超长行 ,可以s/Owner and Operator\nGuide/Installation Guide\n/
实际上, Owner and Operator Guide可能在不同的位置上分成多行,我们可以修改正则,下面是一个完整的脚本:
s/Owner and Operator Guide/Installation Guide/
/Owner/{
$!N
s/ *\n/ /
s/Owner and Operator Guide */Installation Guide\
/
}
D命令:
删除命令D是删除命令d的多行形式,区别在于d删除模式空间的内容并读入新行,从而在脚本顶端重新使用编辑方法。
D只删除多行模式空间的第一个嵌入的换行符以前的内容,它不会导致读入新行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容。
示例:
# 将多个空行减少到一个空行,使用d命令版本
/^$/{
N
/^\n$/d
}
测试文件如下:
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 blank lines.
This is the end.
运行脚本产生一行结果:
[icepp@fc8 test]$ sed -f sed.blank test.blank
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 blank lines.
This is the end.
当有偶数个空行时,所有空行都被删掉。仅当有奇数行时,有一行被保留下来,这是因为d命令删除整个模式空间的内容,一旦遇到第一个空行,就读入下一行,并且两行都被删除。如果遇到第三行,并且下行不为空行,那么d命令就不会执行,因此空行被输出。
我们将d命令换成D命令,测试如下:
[icepp@fc8 test]$ sed -f sed.blank test.blank
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 blank lines.
This is the end.
得到我们预期的结果。多行Delete的工作完成的原因:当遇到两个空行的时候,D命令只删除两个空行的第一个,下次遍历脚本的时候,将导致另一行被读入模式空间。如果那行不为空,那么两行都输出,因此确保了输出一个空行。也就是当模式空间有两个空行的时候,只有第一个空行被删除。当一个空行跟有文本的时候,模式空间的内容都输出。
P命令:
多行Print和小print稍有不同。它输出多行模式空间的第一部分,直到第一个嵌入的换行符。执行完脚本的最后一个命令后,模式空间的内容自动输出(-n选项将抑制这个默认的动作)。
因此,当默认输出被抑制或脚本的控制流更改,以至于不能到达脚本底部的时候,需要使用打印命令P或者p。Print命令经常出现在Next和Delete命令之前。这三个命令能够建立一个输入输出循环,用来维护两行的模式空间,但是一次只输出一行,然后返回到脚本的顶端将所有命令应用于模式空间的第二行。没这个循环,当执行到脚本的最后一个命令的时候,模式空间这两行将被输出。
示例:
测试文件
Here are examples of the UNIX
System. Where UNIX
System appears, it should be the UNIX
Operating System.
测试脚本
/UNIX$/{
N
/\nSystem/{
s// Operating &/
P
D
}
}
执行结果如下
[icepp@fc8 test]$ sed -f sed.Print test.Print
Here are examples of the UNIX Operating
System. Where UNIX Operating
System appears, it should be the UNIX
Operating System.
创建多行模式空间以匹配第一行结尾的“UNIX”和第二行的开始的“System”,如果发现“UNIX System”跨越两行,我们就将它变成“UNIX Operating System”。建立这个循环以返回到脚本顶端,并寻找第二行结尾的“UNIX”。
首先, Next将一个新行追加到模式空间的当前行。在替换命令应用与多行模式空间后,模式空间的第一部分被Print输出,然后被D命令删除。这样,当前行被输出并且新行成为当前行。D命令阻止到达脚本底部输出并清空模式空间的两行,并将控制转移到了脚本顶部,N命令重新将一个新行读入模式空间,这样就形成了循环。
第二部分 H h G g x命令
模式空间(pattern space)是容纳当前输入行的缓冲区。sed还使用一个称为保持空间(hold space)的预留(set-aside)缓冲区。
这部分的命令就是用于在模式空间和保留空间之间移动数据,保持空间用于临时存储,单独的命令不能寻址保持空间或者更改它的内容。
hold命令(H, h)将数据转移至保持空间。
get命令(G, g)将保持空间的数据移至模式空间。
小写字母命令改写目的缓存区的内容,而大写字母命令是追加缓存区的现有内容。
Exchange命令(x)交换保持空间和模式空间的内容。
示例1:反转行的顺序,颠倒1和2开始的行
样本文件
1
2
11
22
111
222
脚本文件
# Reverse flip
/1/{
h
d
}
/2/{
G
}
执行结果
[icepp@fc8 test]$ sed -f sed.flip test.flip
2
1
22
11
222
111
首先, 我们将第一行h复制到保持空间,然后d清除模式空间,sed将读入下一行,G命令将保持空间的内容追加append到模式空间。匹配“1”的行都被复制到保持空间并从模式空间删除,控制转移到脚本的顶端并且不打印那一行。我们保存这两行中的第一行并且直到匹配第二行时才输出它。
Hold 命令后面跟delete命令是一种常见的搭配。没有delete命令,控制将一直进行到脚本的底部,并且模式空间的内容将被输出。如果脚本中使用next(n)命令而不是delete命令,那么模式空间的内容也会被输出。
这仅仅是一个用于演示的逻辑很差的脚本。
示例2:
样本文件
find the Match statement
Consult the Get statement.
using the Read statement to retrieve data
我们将要完成
s/find the Match statement/find the MATCH statement/g
使用脚本
# 将语句的名字变成大写形式
/the .* statement/{
h
s/.*the \(.*\) statement.*/\1/
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
G
s/\(.*\)\n\(.*the \).*\( statement.*\)/\2\1\3/
}
地址将过程限制在匹配the .* statement的行上
h hold命令将当前输入行复制到保持空间。使用样本行”find the Match statement”,我们来显示模式空间和保持空间的内容。应用h命令后:
pattern space: find the Match statement
hold space: find the Match statement
s/.*the \(.*\) statement.*/\1/
这个替换命令从行中取出语句的名字,并且用它来替代整个行
Pattern space: Match
Hold space : find the Match statement
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
这个转换命令将每个小写字母换成大写字母。
pattern space: MATCH
hold space : find the Match statement
G Get命令将保持在保持空间的内容追加到模式空间
pattern space: MATCH\nfind the Match statement
hold space: find the Match statement
s/\(.*\)\n\(.*the \).*\( statement.*\)/\2\1\3/
这个替换命令匹配模式空间的3个部分: 1)嵌入的换行符之前的所有字符 2)从嵌入的换行符开始直到后面跟有一个空格的the,且包括the在内的所有字符 3)以空格并且后面跟有statement开始直到模式空间结尾的所有字符。
pattern space: find the MATCH statement
hold space : find the Match statement
运行脚本后的结果:
find the MATCH statement
Consult the GET statement.
using the READ statement to retrieve data
第三部分 分支和条件指令更改脚本的控制流(: b t)
分支branch和测试命令将脚本中的控制转移到包含特殊标签的行。如果没有指定标签,则控制转移到脚本结尾。分支branch命令用于无条件转移,测试test命令用于有条件转移。
标签是任意不多于7个字符的序列,本身以冒号开始并占据一行。
:mylabel
用法简单示例:
command1
/pattern/b end
command2
:end
command3
command1
/pattern/b dothree
command2
b
:dothree
command3