2009-02-26

sed(3)--命令

在这之前,我们已经用过'='(输出行号和'p'(输出pattern space的内容)这两条命令.现在再详细看其他命令.
'#',注释:

$ cat grep.test
1
1
2
hello

$ sed -e '#comment' -e '/hello/=' grep.test -n
4


'q [EXITCODE]', 退出sed. EXITCODE是可选的退出码:

$ sed -e '2q 3' -e 'p' sed.test
sed\ntest\nsed
sed\ntest\nsed
sedtestsed

$ echo $?
3


'd',删除pattern space的内容,读入下一行,并重新从第一个命令开始执行:

$ cat grep.test
1
1
2
hello

$ sed -e '/2/d' grep.test
1
1
hello


'n',读入下一行内容来覆盖pattern space的内容,并继续执行命令,而不是重新从第一个命令开始执行;如果没有下一行可读则退出.(注意和下面讲到的'N'的区别):

$ sed -e '/2/n' -e 'p' grep.test -n
1
1
hello


'{ COMMANDS }', 一次写多个命令在一起.除了这个方式以外,把命令之间用分号';'隔开也可以一次写多个命令(grep.test的内容请参见上面的例子):

$ { sed -e '{
=
p
}' -n grep.test; }
1
1
2
1
3
2
4
hello

$ sed -e '=;p' grep.test -n
1
1
2
1
3
2
4
hello


's/REGEXP/REPLACEMENT/FLAGS',替换,将与REGEXP这个正则表达式匹配的字符串换成REPLACEMENT. FLAGS可以修改正则表达式的行为,例如让它对大小写不敏感等.

$ sed -e 's/[0-9]/number/' grep.test
number
number
number
hello


s这个命令的FLAGS比较令人感到迷惑,因为它常让人以为这个FLAGS也是命令,让人有时会感到sed的命令的格式很乱,让人不明白为什么sed的命令有的写在正则表达式的前面,有的又写在后面.理解了s这个命令的格式,这些疑云才能一扫而散.

下面是s这个命令的各种FLAGS:
g: 这个标识表示用REPLACEMENT代替所有的匹配:

$ cat grep.test
hello

$ sed -e 's/l/k/' grep.test
heklo

$ sed -e 's/l/k/g' grep.test
hekko


'NUMBER':这个标识表示代替第NUMBER个匹配:

$ sed -e 's/l/k/2' grep.test
helko


'p':这个标识表示,在替换完成之后,输出pattern space的内容.注意这个不是sed的那个'p'命令(虽然它们都是打印pattern space的内容),这只是s这个命令的一个FLAG.

$ cat grep.test
hello
myboy

$ sed 's/l/k/gp' grep.test -n
hekko


上例还说明可以同时使用多个s的FLAG
`w FILE-NAME':如果替换成功,就把替换后的pattern space写入到FILE-NAME这个文件中

$ ls
func.test grep.test sed.test

$ cat grep.test
hello
myboy

$ sed -e 's/l/k/gw kk' grep.test -n

$ ls
func.test grep.test kk sed.test

$ cat kk
hekko


'e':这种在替换成功以后,pattern space的内容就可以一条shell命令来执行,这个shell命令的输出又取代pattern space的内容:

$ sed -e 's/hello/ls/e' grep.test
func.test
grep.test
kk
sed.test
myboy
$ ls
func.test grep.test kk sed.test


'I','i':这两个标识都是表示正则表达式不区分大小写.类似的标识在讲地址的时候已经有提及

$ sed -e 's/L/k/gi' grep.test
hekko
myboy

$ sed -e 's/L/k/gI' grep.test
hekko
myboy


`M',`m':这两个标识让正则表达式里的^和$分别匹配换行符后面的和前面的空串,而不仅仅是行首和行末的空串. 它是Multi-line的缩写. 这个标识和指定地址的时候附在正则表达式后的M标识是一样的.
$ cat sed.test
hello

$ sed -e 's/l/\n/g' -e /he$/Mp sed.test -n
he

o

$ sed -e 's/l/\n/g' -e 's/he$/HE/Mp' sed.test -n
HE

o

$ sed -e 's/l/\n/g' -e 's/he$/HE/p' sed.test -n

$ sed -e 's/l/\n/g' -e /he$/p sed.test -n


s的选项就是上面这些.

sed除了上面说到命令以外,还有一些不那么常用的命令:
`y/SOURCE-CHARS/DEST-CHARS/':把pattern space里的SOURCE-CHARS用DEST-CHARS代替.SOURCE-CHARS和DEST-CHARS的字符数要相同;它们的每个字符是一一对应的,即SOURCE-CHARS的第一个字符用DEST-CHARS的第一个代替,SOURCE-CHARS的第二个字符用DEST-CHARS的第二个代替,依此类推:

$ sed -e 'y/lo/pk/' grep.test
heppk
mybky


`a\'
`TEXT'
:在pattern space后面加一行或多行TEXT:

$ sed -e 'a\
> i am a boy\
> and you?' grep.test
hello
i am a boy
and you?
myboy
i am a boy
and you?


`i\'
`TEXT'
: 在pattern space前面加一行或多行TEXT:

$ cat grep.test
hello
myboy

$ sed -e '2i\
> i am a boy\
> and you ?' grep.test
hello
i am a boy
and you ?
myboy


`c\'
`TEXT'
: 将pattern space的内容变为TEXT:

$ cat grep.test
hello
myboy

$ sed -e 'c\hello\
world' grep.test
hello
world
hello
world


'l N': 输出的时候不可显示的字符(例如换行符等)以C语言的转义字符的形式输出,且每行的末尾加上一个$;如果一行大于N,则分行显示,分行的时候在行末显示一个'\'
$ cat sed.test
hello

$ sed -e 's/l/\n/;l' sed.test -n
he\nlo$


`r FILENAME':把FILENAME这个文件的内容放到输出流(不是pattern space)中,

$ sed -e 'r sed.test' -e '=' grep.test -n
1
sed\ntest\nsed
sedtestsed
test\nsed
2
sed\ntest\nsed
sedtestsed
test\nsed


`w FILENAME':把pattern space的内容输出到FILENAME文件中:

$ ls
func.test grep.test kk orld sed.test

$ sed -e 'w sed.write' grep.test
hello
myboy

$ ls
func.test grep.test kk orld sed.test sed.write

$ cat sed.write
hello
myboy


`N': 读入下一行的内容追加到pattern space,然后继续在当前位置执行命令,即不从头开始执行命令.注意和小写的'n'的区别:

$ cat grep.test
hello
myboy
third
fourth

$ sed -e 'N;=' grep.test
2
hello
myboy
4
third
fourth

$ sed -e 'n;p' grep.test -n
myboy
fourth

$ sed -e 'N;p' grep.test -n
hello
myboy
third
fourth


'P': 输入pattern space的内容,直到遇到换行符
$ cat sed.test
hello

$ sed -e 's/l/\n/g;p' sed.test -n
he

o

$ sed -e 's/l/\n/g;P' sed.test -n
he


'D': 删除pattern space的内容直到遇到换行符.如果这时pattern space还有内容,则从头开始执行脚本,否则读入下一行
例子随后补上...


下面剩下的命令都是用来操作pattern space和hold space
'h':用pattern space的内容覆盖hold space的内容
'H':把pattern space的内容追加到hold space上去
'g':用hold space的内容覆盖pattern space的内容
'G':把hold space的内容追加到pattern space上去
'x':把pattern space和 hold space的内容互换
下面用这其中的G和h来模拟linux的tac这个命令.

$ cat grep.test
hello
myboy
third
fourth

$ tac grep.test
fourth
third
myboy
hello

$ sed -e '1!G;h;$!d' grep.test
fourth
third
myboy
hello





相关文章:
sed(1)--选项
sed(2)--地址

转载请注明出处 http://fornote.blogspot.com

没有评论:

发表评论