标签:
一、Sed简介
Sed:Stream Editor 流式编辑器 又称行编辑器,每次只编辑一行。Sed工作是在“模式空间”中进行的,并不操作源文件。对源文件无危害。
二、Sed使用格式
Sed命令的常用格式如下:
(1)Sed [options] ‘script’ input_file…
(2)Sed [options] –f script_file input_file…
(3)Sed [options] ‘ADDR1,ADDR2command’ input_file…
例如:#sed ’1,2d’ fstab 就可以将fstab的前两行删除并显示出来,但是它不会改变源文件。
#Sed ‘1,2!d’ fstab 表示删除除第一行和第二行之外的所有行。
(4)Sed [options] ‘/PATTERN/command’ input_file……
&:s/l..e/&er/:表示引用前面匹配到的所有字符。
例如:sed ‘/[[:upper:]]/d’ binary.sh 表示删除所有的大写字母的行。
(5)Sed ‘/PATTERN1/,/PATTERN2/command’ input_file……
说明:这表示从第一次被PATTERN1匹配到的行到第一次被PATTERN2匹配到的中间的所有行执行command命令。
三、Sed的常用选项:
-n:只显示sed匹配到的行。其余行不显示。下文有范例。
-i :可以直接操作原文件。默认情况下sed不会改变原文件,但是-i选项可以修改原文件,此选项应慎用。
-r:可以使用标准正则表达式。默认情况下sed只支持基本正则表达式,但是加上-r选项后则支持扩展正则表达式
-e:多脚本共用。可以同时执行多个命令。例如:
[root@localhost ~]# sed -e ‘s@\@H\1@g‘ -e ‘s@\(l..e\)\.@\1r.@g‘ test
He love His lover.
She like Her liker.
Dove love Her liker.
也可以这样用,中间用分号隔开:
[root@localhost ~]# sed ‘s@\@H\1@g;s@\(l..e\)\.@\1r.@g‘ test
四、Sed的常用命令
(1)P:模式空间中的文本在处理之前,每一次都会先显示一下;用p命令后再显示一下,即:匹配到的文本显示两次:例如:
[root@localhost ~]# sed ‘1,2p‘ fstab
/dev/vol0/root / ext3 defaults 1 1
/dev/vol0/root / ext3 defaults 1 1
/dev/vol0/home /home ext3 defaults 1 2
/dev/vol0/home /home ext3 defaults 1 2
LABEL=/boot /boot ext3 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda3 swap swap defaults 0 0
我们可以看到第1,2行显示了两次。如果你只想显示用sed处理的行,则可在其前加-n选项。例如:sed -n ‘1,2p’ fstab 其显示结果如下:
root@localhost ~]# sed -n ‘1,2p‘ fstab
/dev/vol0/root / ext3 defaults 1 1
/dev/vol0/home /home ext3 defaults 1 2
(2)a \:表示在模式匹配到的行后面添加新内容;
i \:表示在模式匹配到的行前面添加新内容;
/n:实现添加多行。如下例所示:
[root@localhost ~]# sed ‘/#/a \ This is a comment line.\nIt can be ignore.‘ test.sh
#!/bin/bash
This is a comment line.
It can be ignore.
#
This is a comment line.
It can be ignore.
JUSER() {
if id -u root &> /dev/null;then
echo "Exists"
else
echo "No this user."
fi
}
JUSER &> /dev/null
echo $?
这表示在#行的后面加上两行文字,如果将a换成i则表示在#行的前面添加文字。
注意:sed ‘/#/!i \ This is a comment line.\nIt can be ignore.‘ test.sh,如果在i前面加!表示对除了匹配到的行的其他行的前面添加以上两行。这样大家基本明白了a,i命令的使用方法了吧。
(3)r FILE:表示读取某一个文件。例如:
root@localhost ~]# sed ‘2r c.txt‘ c.sh #表示在c.sh的第二行添加c.txt的内容。
#!/bin/bash
#
This is my first lesson.
Think you!
line 1
line 2
line 3
[root@localhost ~]# sed ‘/^#/r c.txt‘ c.sh #表示在c.sh的#开头的行后面添加c.txt的内容。
#!/bin/bash
This is my first lesson.
Think you!
#
This is my first lesson.
Think you!
line 1
line 2
line 3
(4)w FILE: 可以将模式匹配到的行保存下来。例如:
root@localhost ~]# cat c.sh #显示c.sh中的内容
#!/bin/bash
#
line 1
line 2
line 3
[root@localhost ~]# sed -n ‘/^#/w cc.sh‘ c.sh #将c.sh文件中以#开头的行保存在cc.sh中
[root@localhost ~]# cat cc.sh #cc.sh的内容
#!/bin/bash
#
(5)s:s/PATTERN/string/[g|i] 表示搜索符号PATTERN的内容,将其替换为string。
g:表示将搜索到的内容全部替换。
i:表示将搜索到的内容忽略大小写。
如果PATTERN中含有与分隔符相同的字符时,可以将分隔符替换为其他符号。例如:s@PATTERN@string@[g|i]
范例如下:
[root@localhost ~]# cat test #显示test的内容
He love his love.
She like her like.
Dove love her like.
[root@localhost ~]# sed ‘s@\(l..e\)\.@\1r.@‘ test #在最后一个单词后面加r,注意第.
He love his lover. #前面要加转义字符\
She like her liker.
Dove love her liker.
[root@localhost ~]# sed ‘s@\@H\1@g‘ test #将以h开头的单词替换
He love His love. #为以H开头
She like Her like.
Dove love Her like.
(6)n:以覆盖的方式读去下一行。
N:以追加的方式读取下一行。例如:
[root@localhost ~]# cat test #test中的内容
He love his love.
She like her like.
Dove love her like.
four line
[root@localhost ~]# sed -n ‘n;p‘ test #使用n时的效果
She like her like.
four line
[root@localhost ~]# sed ‘n;d‘ test #只显示偶数行。
He love his love.
Dove love her like.
[root@localhost ~]# sed -n ‘N;p‘ test #使用N时的效果
He love his love.
She like her like.
Dove love her like.
four line
[root@localhost ~]# sed ‘N;N;s@\n@ @g‘ test #表示将前三行合并为一行
He love his love. She like her like. Dove love her like.
four line
[root@localhost ~]# sed ‘/\.$/!N;s@\n@ @g;s/bad animal/BAD ANIMAL/g‘ test
He love his love.
She like her like.
Dove love her like.
four line Wendy is BAD ANIMAL.
Blair is a BAD ANIMAL.
这题目较复杂:(1)/\.s/!N:表示先搜索不已点号结尾的行,(2)s@\n@ @g:将搜索到的行去掉换行符 (3)将小写的bad animal 替换为BAD ANIMAL.
(7) h:将模式空间中的内容以覆盖的方式复制到保留空间。
H:将模式空间中的内容以追加的方式复制到保留空间。
g:将保留空间的内容以覆盖的方式复制到模式空间。
G:将保留空间的内容以追加的方式复制到模式空间。例如:
[root@localhost ~]# cat newfile #显示文件中的内容
line 1
line 2
line 3
[root@localhost ~]# sed -n ‘h;n;G;h;n;G;p‘ newfile #将文件中的行倒序排列
line 3
line 2
line 1
(8)b:跳转,掠过符合条件的行。例如:
[root@localhost ~]# sed ‘1b;y/123/456/‘ newfile
line 1
line 5
line 6
此例表示:跳过第一行,将其他各行的123替换为456;其中y表示替换的意思。
b lable:表示跳转到某个位置。例如
[root@localhost ~]# cat newfile
line 1
line
line 3
line
[root@localhost ~]# sed ‘/.*[[:digit:]].*/b para;s/.*/% &/;:para;s/.*[0-9].*/# &/g‘ newfile
# line 1
% line
# line 3
% line
此例表示,将带数字的行前添加#,不带数字前添加%;定义para为跳转符。这个参数可以随意指定。
本文只是对sed的一些常用命令和选项做介绍,其余命令可查看帮助手册。谢谢!
最近在处理一个文本,打算用sed命令来处理,但是由于经常情况下都是做简单的替换,所以对sed不是很熟悉,最近两天由于项目工作量比较小,所以就今天抽空整体学习下了sed。
bc
bbbbbbbbbb
dfg
jjjjjjjjj
hjk
sed是简单小巧但功能非常强大的工具。在上一篇博客中自己注解了sed的info文档中那些比较复杂的脚本示例,最近工作中使用到sed,复习了一下,再做一篇总结放在这里:
练习几个例子,以便将来温习:准备以下文件:
sed
1.sed
[root@stu93 sed]# sed -r ‘/\n!G;s/(.)(.*\n)/&\2\1;//D;s/.//‘ abc.txt
回去查
流编辑器 stream editer,是以行为单位的处理程序
sed 流编辑器 stream editer
语法
sed [options] ‘command‘ in_file[s]
options 部分
-n 阻止输入行自动输出
-e
-i
-f 脚本文件
-r 支持拓展正则
command 部分
‘[地址1,地址2] [函数] [参数(标记)]‘
定址的方法 1.数字 2.正则
数字
十进制数
1 单行
1,3 范围 从第一行到第三行
2,+4 匹配行后若干行
4,~3 从第四行到下一个3的倍数行
2~3 第二行起每间隔三行的行
$ 尾行
1! 除了第一行以外的行
2.sed -n ‘‘ /etc/passwd 阻止输入行自动显示
3.sed -n ‘p‘ /etc/passwd
4.‘cmd‘
定址 函数[标记];函数
5. [root@stu93 ~]# sed -n ‘1{p;p}‘ /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
[root@stu93 ~]# sed -n ‘1p;3p‘ /etc/passwd
[root@stu93 ~]# sed -n ‘/^id/s/[0-6]/3/p‘ /etc/inittab
id:3:initdefault:
6 [root@stu93 ~]# cat -n /etc/passwd | sed ‘6,~3p‘倍数行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6,+3p‘重复行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6~3p‘间隔行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6p‘指定行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6!p‘除了6行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘$p‘最后一行
[root@stu93 ~]# sed -n ‘/root\|seker/p‘ /etc/passwd 含root和seker的行
[root@stu93 ~]# sed -n ‘/^root/,/^adm/p‘ /etc/passwd 以root和adm开头的行
[root@stu93 sed]# sed ‘2c xyz.txt‘ abc.txt
aaaaaaaaaaa
xyz.txt
ccccccccccc
7. 基本正则
正则介绍
^ 行首
$ 行尾
. 除了换行符以外的任意单个字符
* 前导字符的零个或多个
.* 所有字符贪婪性取多不取少
[] 字符组内的任一字符
[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
^[^] 非字符组内的字符开头的行
[a-z] 小写字母
[A-Z] 大写字母
[a-Z] 小写和大写字母
四则运算 [+ - * /]不可以 [- + * /]减号方前面就可以了
[0-9] 数字
\< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
\> 单词尾
. 匹配除换行符职位的任意单个字符,awk中可以匹配换行符
* 匹配任意一个(包括零个)在它前面的字符
[...] 匹配方括号中的任意一个字符,^为否定匹配, -表示字符的范围
^ 作为正则表达式的第一个字符,匹配行的开始。在awk中可以嵌入换行符
$ 作为正则表达式的最后一个字符,匹配行的结尾。在awk中可以嵌入换行符
\{n,m\} 匹配出现的n到m次数, \{n\}匹配出现n次。\{n,\}匹配至少出现n次
\ 转义字符
\< \>单词
sed ‘/正则/‘
8. 扩展正则
sed -r ‘拓展正则‘
grep -E
egrep
grep \
+ 匹配前面的正则表达式的一次出现或多次出现
? 匹配前面的正则表达式的零次出现或一次出现
| 可以匹配前面的或后面的正则表达式(替代方案)
() 对正则表达式分组
{n,m} 匹配出现的n到m次数, {n}匹配出现n次。{n,}匹配至少出现n次,大多数awk都不支持,用于POSIX egrep和POSIX awk
[root@stu93 ~]# cat 4
egg
cow
[root@stu93 ~]# sed -e ‘s/egg/cow/‘ -e ‘s/cow/pig/ ‘ 4
pig
pig
[root@stu93 ~]# sed -e ‘s/cow/pig/‘ -e ‘s/egg/cow/‘ 4
cow
pig
此时应该考虑顺序问题 可以变换下替换顺序
扩展正则 加 -r 参数 或转义
sed -n ‘/roo\?/p‘ /etc/passwd
sed -rn ‘/roo?/p‘ /etc/passwd
? 前导字符零个或一个
+ 前导字符一个或多个
abc|def abc或def
a(bc|de)f abcf 或 adef
x\{m\} x出现m次
x\{m,\} x出现m次至多次(至少m次)
x\{m,n\} x出现m次至n次
函数
增删改
a\ 后插
c\ 替换
i \前插
d 删除
这些命令每一个都要求后面加一个反斜杠用于转义第一个行尾
输入输出
p 打印匹配的行 一般和 -n 参数连用,以屏蔽默认输出
r 从文件中读入
w 写入到文件中
y 字符替换(变形)
q 退出
控制流
! 命令取反 例: 1!d 删除第一行以外的行
{} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法
= 打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n ‘2{=;p}‘ infile
n 读入下一行到模式空间 例:‘4{n;d}‘ 删除第5行
N 是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令
R 两个文件个行输出
r 输出一行之后另个文件全不输出之后再输出前一个文件的另一行
c
i 对内存操作
P 输出当前模式空间中匹配的第一部分(第一个字符到第一个换行符为止)
D 从第一个字符删除到第一个换行符结束 它不会导入新的输入行 而是返回输入行顶部继续执行
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/gp‘ /etc/passwd
ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/2p‘ /etc/passwd
root:x:0:0:ABCDEF:/root:/bin/bash
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/3p‘ /etc/passwd
root:x:0:0:root:/ABCDEF:/bin/bash
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/gp‘ /etc/passwd
ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin
[root@stu93 ~]#cat a.txt
123
123
123
[root@stu93 ~]#sed -r ‘$!N; /^(.*)\n\1$/!P;D‘ a.txt
123
高级命令
NDP sed -r ‘$!N;/^(.*)\n\1$/!p;D‘
[root@stu93 ~]# cat a
this is the unix
system and unix is like the
unix system
[root@stu93 ~]# sed ‘N;s/\n/‘‘/;s/ system/ opting system/;P;D‘ a
this is the unix opting system and unix is like the
unix opting system
:
替换
s 字符串替换 s/old/new/
$ sed -n ‘s/root/ABCDEF/p‘ /etc/passwd
ABCDEF:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin
定址
[root@stu93 ~]# cat a.txt
beijing ,chain
shanghai ,chain
aaa
tianjin .chain
bbb
chengdu .chain
[root@stu93 ~]# sed ‘/^aaa/,/^bbb/{s/tianjin/TJ/;s/chain/CN/}‘ a.txt
beijing ,chain
shanghai ,chain
aaa
TJ .CN
bbb
chengdu .chain
[root@stu93 sed]# sed -n ‘1,3s/root/AA/gp‘ passwd
AA:x:0:0:AA:/AA:/bin/bash
[root@stu93 ~]# sed ‘=‘ /etc/passwd | sed ‘N;s/\n/ /‘ 每两行处理为一行
三行处理成一行
[root@stu93 ~]# cat b.txt
2010-09-23
192.168.0.1
shutdown
2010-09-22
192.168.0.2
reboot
2010-09-24
192.168.0.3
init 0
[root@stu93 ~]# sed ‘N;N; s/\n/ /g‘ b.txt
2010-09-23 192.168.0.1 shutdown
2010-09-22 192.168.0.2 reboot
2010-09-24 192.168.0.3 init 0
连着的多个空行变为一个空行输出
[root@stu93 ~]# cat c.txt
1111111
3333
666666666
100000000
[root@stu93 ~]# sed ‘/^$/{N; /^\n$/D }‘ c.txt D 删除第一个空行
[root@stu93 ~]# sed ‘/^$/d;$!G‘ c.txt $!G表示最后一行不执行G规则
1111111
3333
666666666
100000000
[root@stu93 ~]# time sed ‘2q‘ a.txt q 对大文件操作较快
[root@stu93 ~]# time sed -n ‘1,2p‘ a.txt 对小文件可以
\(\) 保存被匹配的字符 以备反向引用\N时使用 最多9个标签 标签顺序从左至右
& 替换时使用,在不定义标签时使用(反向引用)
试做:
删除第一个单词
删除最后一个单词
将第一个单词和最后一个单词兑换位置
y 字符替换(变形)
工作模式 模式空间和保持空间介绍
[root@stu93 ~]# sed ‘1{p;p}‘ a.txt
11111111
11111111
11111111
22222222
33333333
44444444
55555555
66666666
置换 模式空间和保持空间(暂存空间)
h 把模式空间内容覆盖到保持空间中
H 把模式空间内容追加到保持空间中
g 把保持空间内容覆盖到模式空间中
G 把保持空间内容追加到模式空间中
x 交换模式空间与保持空间的内容
[root@stu93 ~]# cat test.sh
1111111
2222222
3333333
4444444
[root@stu93 ~]# sed ‘{1h;2,3H;4G}‘ ./test.sh
1111111
2222222
3333333
4444444
1111111
2222222
3333333
[root@stu93 ~]# sed ‘{1h;2x;3g;$G}‘ ./test.sh
1111111
1111111
2222222
4444444
2222222
#
[root@stu93 sed]# sed ‘1H;2,3{G};$g‘ xyz.txt
1111111
2222222
1111111
3333333
1111111
1111111
[root@stu93 sed]# sed ‘1h;2,3H;$!G‘ xyz.txt
1111111
1111111
2222222
1111111
2222222
3333333
1111111
2222222
3333333
4444444
cmd qianhou
sed null\n
1h 11111111
$!G 1111 11111111
==>1111 1111
2H 22221111 2222
$!G 2222 1111 2222 11112222
==>2222 1111 2222
3H 33331111 2222 3333
$!G 3333 1111 2222 3333
==>3333 1111 2222 3333
$!G 4444
[root@stu93 sed]# tac xyz.txt
4444444
3333333
2222222
1111111
[root@stu93 sed]# sed ‘4G;2,3{G;h;d};1{h;d};‘ xyz.txt
[root@stu93 sed]# sed ‘4G;3{G;h;d};2{G;h;d};1{h;d};‘ xyz.txt
4444444
3333333
2222222
1111111
4G 44444/n/n
=>4444/n
3{G;h;d} 3333 /n
3333 3333
3333
==>3333
2{G;h;d} 2222
2222 2222
2222
==>2222
1{h;d} 1111 1111
1111
==>1111
[root@stu93 sed]# sed ‘1!G;h;$!d‘ xyz.txt
试做题
奇数行和偶数行互换
[root@stu93 ~]# cat 3 .txt
1
2
11
22
111
222
[root@stu93 ~]# sed -e ‘/1/{h;d}‘ -e ‘/2/{G}‘ 3.txt
每行的后面加空行
[root@stu93 ~]# sed ‘G‘ 3.txt
每行的后面加2个空行
[root@stu93 ~]# sed ‘G;G‘ 3txt
显示文件的前10行
[root@stu93 ~]# sed -n ‘1,10p‘ /etc/passwd
每行的前面加空行
[root@stu93 ~]# sed -e ‘x;P;x‘ 3.txt
将第一行插入到每个偶数行的后面
$ sed ‘1h;0~2G‘ a.txt
11111111
22222222
11111111
33333333
44444444
11111111
55555555
66666666
11111111
$
颠倒输出
[root@stu93 ~]# sed ‘1!G;h;$!d‘ rev.txt
[root@stu93 ~]# sed -n ‘1!G;h;$p‘ 3
xyz
def
abc
脚本方法
四 编写sed脚本
模式空间
sed -e ‘s/pig/cow/’ -e ‘s/cow/horse/’
sed -e ‘s/cow/horse/’ -e ‘s/pig/cow/’
寻址上的全局透视
全局操作 范例file2.txt
$ sed ‘/Beijing/s/CN/China/g‘ file2.txt
删除所有的行
d
删除文件的最后两行
[root@stu93 ~]# sed ‘N;$!P;$!D;$d‘ c.txt
只删除第一行
1d
使用寻址符号$,删除最后一行
$d
删除空行,正则表达式必须封闭在斜杠//当中
/^$/d
删除.TS和.TE标记的tbl输入
/^\.TS/,/^\.TE/d
删除第五行到结尾所有的行
5,$d
混合使用行地址和模式地址
$ sed ‘1,/^$/d‘ file2.txt
删除除了那些行以外的行
1,5!d
分组命令
/^\.TS/,/^\.TE/{
/^$/d
}
/^\.TS/,/^\.TE/{
/^$/d
s/^\.ps 10/.ps 8/
s/^\.vs 12/.vs 10/
}
-f 参数 引用脚本(脚本的末尾不能有空格制表符或其他文本)
# cat sed.sh
2,4d
s/777/seker/
s/999/seker&seker/
# sed -f sed.sh test.txt
1111111
5555555
6666666
seker7777
8888888
seker999seker9999
#
在脚本中指明解释器为sed
# cat sed.sh
#!/bin/sed -f
2,4d
s/777/seker/
s/999/seker&seker/
# ./sed.sh test.txt
1111111
5555555
6666666
seker7777
8888888
seker999seker9999
#
高级流控命令 b分支 t测试
分支命令用于无条件转移,测试命令用于有条件转移
分支 branch
跳转的位置与标签相关联
如果有标签则跳转到标签所在的后面行继续执行
如果没有标签则跳转到脚本的结尾处.
标签 以冒号开始后接标签名 不要在标签名前后使用空格
跳转到标签指定位置
:top
cmd1
cmd2
/aa/b top
cmd3
cmd1
/aa/b end
cmd2
:end
cmd3
cmd1
/aa/b dothree
cmd2
b
:dothree
cmd3
[root@stu254 ~]# grep seker /etc/passwd
seker:x:500:500::/home/seker:/bin/bash
[root@stu254 ~]#
[root@stu254 ~]# grep seker /etc/passwd |sed ‘:top;s/seker/blues/;/seker/b top;s/5/555/‘
blues:x:55500:500::/home/blues:/bin/bash
[root@stu254 ~]#
命令分析:让单次替换(cmd1)循环执行,直到条件不满足
:top; 定义一个top标签
s/seker/blues/; cmd1
/seker/b top; 如果模式匹配则跳转到top标签
s/5/555/ 当上一条模式不匹配时,既会继续执行这一条
选择执行
[root@stu254 ~]# grep ‘seker‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/‘
blues:x:66600:500::/home/seker:/bin/bash
[root@stu254 ~]#
zorro:x:501:501::/home/zorro:/bin/bash
[root@stu254 ~]# grep ‘zorro‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/‘
zorro:x:6665501:501::/home/zorro:/bin/bash
[root@stu254 ~]#
命令分析: 执行cmd1,再去模式匹配,成功则跳转到cmd3开始执行,否则(模式不匹配)会按命令顺序逐个执行
s/seker/blues/; cmd1
/seker/b end;
s/5/555/; cmd2
:end;
s/5/666/ cmd3
另一种选择执行
[root@stu254 ~]# grep ‘seker‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/‘
blues:x:66600:500::/home/seker:/bin/bash
[root@stu254 ~]# grep ‘zorro‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/‘
zorro:x:55501:501::/home/zorro:/bin/bash
[root@stu254 ~]#
命令分析: 执行cmd1;模式匹配cmd2成功则执行cmd3;否则执行cmd2,再跳转到脚本末尾
s/seker/blues/; cmd1
/seker/b end;
s/5/555/; cmd2
b;
:end;
s/5/666/ cmd3
测试命令,如果前一个替换命令执行成功则跳转到脚本末尾 (case结构)
[root@stu254 ~]# grep ‘seker‘ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/‘
ABC:x:500:500::/home/seker:/bin/bash
[root@stu254 ~]# grep ‘zorro‘ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/‘
zorro:x:501:501::/DEF/zorro:/bin/bash
[root@stu254 ~]#
与标签关联,跳转到标签位置
[root@stu254 ~]# grep ‘seker‘ /etc/passwd |sed ‘s/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/‘
ABC:x:500:500::/home/seker:/bin/XYZ
[root@stu254 ~]#
[seker@seker ~]$ grep ‘zorro‘ /etc/passwd |sed ‘s/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/‘
zorro:x:501:501::/DEF/zorro:/bin/bash
[seker@seker ~]$
runsed 对输入文件作永久性改变
#!/bin/bash
for x
do
echo "editing $x: \c"
if test "$x" = sedscr;then
echo "not editing sedscript"
elif test -s $x;then
sed -f sedscr $x > /tmp/$x$$
if test -s /tmp/$x$$
then
if cmp -s /tmp/$x$$
then
echo "file not changed: \c"
else
mv $x.bak # save original, just in case
cp /tmp/$x$$ $x
fi
echo "done"
else
echo "Sed produced an empty file\c"
echo "- check your sedscript."
fi
rm -f /tmp/$x$$
else
echo "original file is empty."
fi
done
echo "all done"
| s | d | a | i | c | p | l | r | w | y | ! | n | q | = | # | N | D | P | h | H | g | G | x | b | t |
s
函数参数 s 表示替换(substitute)文件内字串。其指令格式如下:[address1[
,address2]] s/pattern/replacemen/[flag].函数参数 s 最多与两个位址参数配合
pattern : 它为 reguler expression
字串。它表示文件中要被替换的字串
replacement : 它为一般字串。但其内出现下列字元有特别意义:
& : 代表其前
pattern 字串。例如 sed -e ‘s/test/& my car/‘ 指令中 ,
& 代表 pattern 字串 "test"。故执行後 , 资料档的 "test" 被替换成
"test my car"
\n : 代表 pattern 中被第 n 个 \(
、\)(参照[附录 A]) 所括起来的字串。例如sed -e ‘s/\(test\) \(my\) \(car\)/[\2 \3
\1]/‘ 指令中 , \1 表示 "test"、\2 表示 "my"、\1 表示 "car" 字串。故执行後 , 资料档的
"test my car" 被替换成 "[my car test]"
\ : 可用它来还原一些特殊符号(如上述的
& 与 \ )本身字面上的意义 , 或用它来代表换行。
flag : 主要用它来控制一些替换情况:
当 flag 为 g 时 ,
代表替换所有符合(match)的字串
当 flag 为十进位数字 m 时 , 代表替换行内第 m
个符合的字串
当 flag 为 p 时 , 代表替换第一个符合
pattern 的字串後 , 将资料输出标准输出档
当 flag 为 w wfile 时 , 代表替换第一个符合
pattern 的字串後 , 输出到 wfile 档内(如果 wfile 不存在 , 则会重新开启名为 wfile
的档案)
当没有 flag 时 , 则将资料行内第一个符合
pattern 的字串以 replacement 字串来替换
delimiter : 在 "/pattern/replace/[flag] " 中 "/"
被当成一 delimiter。除了空白(blank)、换行(newline) 之外,使用者可用任何字元作为
delimiter。例如下述编辑指令s#/usr#/usr1#g,上述命令中 \verb|#| 为 delimiter。如果用 "/"
做 delimiter , 则 sed 会将 pattern 与 replacement 中的 "/"当成 delimiter
而发生错误
例:替换 input.dat 档内 "1996" 字串成 "1997" , 同时将这些资料行存入
year97.dat 档内
说明:用函数参数 s 指示 sed 将 "1996" 字串替换成 "1997" , 另外用 s
argument 中的 flag w 指示sed将替换过的资料行存入 year97.dat 档内
sed -e ‘s/1996/1997/w year97.dat‘ input.dat
语法格式
s/Regexp/Replacement/Flags
分隔字符/可以用其他任意一个单字符代替,若在Regexp或Replacement中有分隔字符,必须要进行转义操作。
功能说明
命令s可能是sed最重要的命令,基本功能就是:用指定的Regexp试图匹配模版空间中的数据,若成功,就用指定的Replacement替换模版空间中匹配的部分。
替换选项说明
1、\n
替换正则表达式Replacement中可含有后向引用中的\n(n是1至9),引用前面定义的子表达。
2、&
代表模版空间中的整个匹配部分。
3、\L GNU的扩展功能
将在其后的替换部分转换成小写字母,直到发现一个\U或\E。
4、\l GNU的扩展功能
将下一个字符转换成小写字母。
5、\U GNU的扩展功能
将在其后的替换部分转换成大写字母,直到发现一个\L或\E。
6、\u GNU的扩展功能
将下一个字符转换成大写字母。
7、\E GNU的扩展功能
停止由\L或\U指示开始的大小写转换。
所以替换正则表达式Replacement中要含有字符\或&或字符串\n的本身,必须要进行转义操作,即变成:\\、\&和\\n的形式。
注意:为什么在Replacement中不用重复元字符:\+、\?、\{、\}
d
函数参数 d 表示删除资料行,其指令格式如下:[address1[ ,address2]]
d 对上述格式有下面几点说明:函数参数 d 最多与两个位址参数配合
sed 执行删除动作情况如下:将 pattern space
内符合位址参数的资料删除,将下一笔资料读进 pattern space重新执行 sed script
删除命令,清空模版空间中的数据,立即开始sed 下一处理循环。
a
函数参数 a 表示将资料添加到文件中。其指令格式如下: [address1]
a\ 使用者所输入的资料 对上述格式有下面几点说明:函数参数 a
最多与一个位址参数配合
函数参数 a 紧接着 "\"
字元用来表示此行结束,使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
sed 执行添加动作情况如下 : 当 pattern space 内资料输出後 , sed
跟着输出使用者所输入的资料
例:添加 "多工作业系统" 在含 "UNIX" 字串的资料行後。
sed -e ‘/UNIX/a\
多工作业系统
‘ input.dat
i
函数参数 i 表示将资料插入文件中。其指令格式如下:[address1]
i\ 使用者所输入的资料 对上述格式有下面几点说明:函数参数 i
最多与一个位址参数配合
函数参数 i 紧接着 "\" 字元用来表示此行结束 ,
使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
sed 执行插入动作的情况如下 : 在 pattern space 内资料输出前 , sed
先输出使用者所输入的资料
例:将 "文章版权属於中央研究院" 插在 input.dat 档中含 "院长 : 李远哲"
的资料行之前
sed 命令列如下:
sed -e ‘/院长 : 李远哲/i\
文章版权属於中央研究院
‘ input.dat
c
函数参数 c 表示改变文件中的资料。其格式如下:[address1[ ,address2]]c使用者所输入的资料 对上述格式有下面几点说明:函数参数 c 最多与两个位址参数配合
函数参数 c 紧接着 "\" 字元用来表示此行结束 ,
使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
sed 执行改变动作的情况 : 在 pattern space 内资料输出时 , sed
改变它成为使用者所输入的资料
p
显示命令,作用是显示模版空间的数据,通常和命令行选项-n 同时使用。
常用在多个命令要对相同 sed 地址行进行处理时
函数参数 p 表示印出资料。其指令格式如下:[address1[ , address2]]
p 对上述格式有下面几点说明:函数参数 p 最多与两个位址参数配合
sed 执行印出动作的情况如下 : sed 拷备一份 pattern space
内容至标准输出档
l
函数参数 l , 除可将资料中的 nonprinting character 以
ASCII码列出外 , 其於均与函数参数 p 相同。例如 , 将下面 input.dat 档中的 ^[ 以 ASCII
码印出
The Great ^[ is a movie starring Steve
McQueen.
执行命令 sed -e ‘l‘ input.dat 後 , 则输出结果如下:
The Great \003 is a movie starring Steve
McQueen.
The Great is a movie starring Steve
McQueen.
上述第二行资料为 sed 的自动输出
r
函数参数 r 表示读入它档案内容到文件中。其指令格式如下:[address1] r
它档名称 对上述格式有下面几点说明:函数参数 r 最多与一个位址参数配合
在指令中 , 函数参数 r 与它档名称间 , 只能有一空格
sed 执行读入动作的情况如下 : 在 pattern space 内资料输出後 , sed
读出它档的内容跟着输出。当它档不存在时,sed 照样执行其它指令而不会有任何错误讯息产生
w
函数参数 w 表示将文件中的写到它档内。其指令格式如下:[address1[
,address2]] w 它档名称 对上述格式有下面几点说明:函数参数 w
最多与两个位址参数配合
在指令中 , 函数参数 w 与它档名称间 , 只能有一空格
sed 执行写出动作的情况如 : 将 pattern space 内资料写到它档内。资料写入时 ,
会取代(overwrite)原来档案内的资料。另外 , 当它档不存在时 , sed 会重新产生(creat)它
y
函数参数 y 表示转换资料中的字元。其指令格式如下:[address1[ ,address2]]y
/xyz.../abc.../ 对上述格式有下面几点说明:函数参数最多配合两个位址参数
指令中 , /abc.../xyz.../(x、y、z、a、b、c 代表某些字元) 为 y 的
argument 。其中 abc... 与 xyz... 的字元个数必须相同
sed 执行转换时 , 将 pattern space 内资料内的 a 字元转换成 x 字元 、b
字元转换成 y 字元 、c 字元转换成 z 字元 ...。
!
函数参数 ! 表示不执行函数参数。当有如下指令时,[address1[ , address2]]
! 函数参数表示,对符合位址参数之资料不执行函数参数。例如删除,除了含 "1996" 字串,所有资料行,则执行如下命令sed -e
‘/1996/!d‘ input.dat
n
函数参数 n 表示读入下一行资料。其指令格式如下:[address1[ ,address2]]
n 对格式有下面几点说明:函数参数 n 最多配合两个位址参数
sed 执行读入下一行动作的情况如下:输出在 pattern space 的资料,将下一笔资料读到
pattern space,执行下一个编辑指令。
新行命令,作用是显示模版空间的数据(无选项-n时)后,sed立即读取新的一行来取代模版空间
的数据,此时若没有待输入行了,sed直接退出,不再处理任何命令。
例:输出 input.dat 档内偶数行资料。假设 input.dat 档内容如下:
The
UNIX
Operation
System
说明: 在命令列上以选项 -n , 将资料输出的控制权转给指令,利用函数参数 n
将下一行资料(偶数行)取代 pattern space 内的资料行(奇数行),利用函数参数 p 将 pattern space
内的资料(偶数行)输出,最後 , 整个输出只有原先档内的偶数行资料
sed 命令列如下:sed -n -e ‘n‘ -e ‘p‘ infro.dat
执行上述命令後,输出的结果如下 :
UNIX
System
q
函数参数 q 表示跳离 sed 。其指令格式如下:[address1]
q 对上述格式有下面几点说明:函数参数 q 最多配合一个位址参数
sed 执行跳离动作时 , 它停止输入 pattern space 资料 ,
同时停止资料送到标准输出档
退出命令,只接受单一匹配的sed地址。表示退出sed,不再处理任何命令或输入,若没有选项
-n ,在退出前会显示当前模版空间中的数据。
退出并返回指定的退出代码,是GNU的扩展功能。
例 :
题目: 对文件档执行 script_file 内的编辑指令 , 除非遇到 "Linux"
字串
sed 命令列如下:sed -e ‘/Linux/q‘ -f script_file
input.dat
=
函数参数 = 表示印出资料的行数。其指令格式如下: [address1 ,[address2]]
= 对上述格式有下面几点说明:函数参数 = 最多配合两个位址参数
执行时 , 行数将在资料输出前先输出
例:印出 input.dat 档内资料行数。假设 input.dat 的内容如下:
The UNIX
Operating System
说明:用函数参数 = 来印出资料的行数 sed 命令列如下:
sed -e ‘=‘ input.dat
执行上述命令後 , 输出的结果如下:
1
The UNIX
2
Operating System
#
在 script file 内 , 函数参数 # 後的文字为注解。当注解文字超过多行时 ,
其行间须以 "\" 换行字元相隔
注释命令,不允许有sed地址。用于对sed脚本的注解和说明,此字符后内容即为注释直到行尾。
1、有些版本的sed只允许脚本有一行注释,且必须是第一行,即脚本的第一个字符必是# 。
2、当sed脚本的前两个字符是#n时,表示强制打开选项-n
(不自动显示);同时考虑上面要求,
注释若是以#n开始的,必须改成#N或# n的形式。
N
函数参数 N 表示添加下一笔资料在 pattern space
内。其指令格式如下:[address1 ,[address2]] N
对上述格式有下面几点说明:函数参数 N 最多配合两个位址参数
sed 执行时 , 将下一行资料读入并添加在 pattern space 内 ,
资料行间以换行字元(embedded newline character)分隔。此外 , 在替换时 , 换行字元可用 \n 来
match
例:将下述两行资料合。假设 input.dat 的内容如下:
The UNIX
Operating System
说明:先利用函数参数 N 将两行资料置於 pattern space内,再利用函数参数 s/\n/
/ 将两行资料间的分隔号 \n 以空白替代 , 如此两行资料变成一行输出
sed 命令列如下: sed -e ‘N‘ -e ‘s/\n/ /‘ input.dat
D
函数参数 D 表示删除 pattern space
内的第一行资料。其指令格式如下:[address1,address2]D 对上述格式有下面几点说明:函数参数 D
最多配合两个位址参数
函数参数 D 与 d 的比较如下:当 pattern space 内只有一资料行时 , D 与 d
作用相同。当 pattern space 内有多行资料行时D 表示只删除 pattern space 内第一行资料 ; d
则全删除。D 表示执行删除後 , pattern space 内不添加下一笔资料 , 而将剩下的资料重新执行 sed script ;
d 则读入下一行後执行 sed script
P
函数参数 P 表示印出 pattern space 内的第一行资料。其指令格式如下:
[address1,address2] P 对上述格式有下面几点说明:函数参数 P
最多配合两个位址参数
P 与 p , 除了面对的 pattern space 内的资料行数不同外 ,
其它均相同
例:输出 input.dat 档内奇数行资料。假设 input.dat 档内容如下:
The
UNIX
System
说明: 在命令列上以选项 -n , 将资料输出的控制权转给指令。利用函数参数 N 将偶数行添加至
pattern space 内奇数行後。利用函数参数 P 将 pattern space 内的第一行(奇数行)输出。在奇数行输出後 ,
pattern space 内剩下的资料行(偶数行)则被放弃输出。最後 , 整个输出只有原先的奇数行资料。
sed 命令:sed -n -e ‘N‘ -e ‘P‘ infro.dat
执行上述命令後 , 输出的结果如下:
The
System
h
函数参数 h 表示暂存 pattern space 的资料至 hold
space。其指令格式如下:[address1 ,[address2]] h
对上述格式有下面几点说明:函数参数 h 最多配合两个位址参数
sed 执行暂存动作时 , 会盖掉(overwrite) hold space 内原来的资料,当
sed 全部执行结束时 , hold space 内资料会自动清除
H
函数参数 H 与 h 唯一差别是 , sed 执行 h 时 , 资料盖掉(overwrite)
hold space 内原来的资料 , 而 H , 资料则是 "添加(append)" 在 hold space 原来资料後。
g
函数参数 g 表示与函数参数 h 相反的动作 , 它表示将 hold space 内资料放回
pattern space 内。其指令格式如下:[address1,address2]g 函数参数 g
最多配合两个位址参数
sed 执行放回动作时 , 资料盖掉(overwrite)pattern space
内原来的资料
G
函数参数 G 与 g 唯一差别是 , sed 执行 g 时 , 资料盖掉(overwrite)
pattern space 内原来的资料 , 而 G , 资料则是 "添加(append)" 在 pattern space
原来资料後
x
函数参数 x 表示交换 hold space 与 pattern space
内的资料。其指令格式如下: [address1 ,[address2]] x 函数参数 x
大部份与其它处理 hold space 的函数参数一起配合
例如 , 将 input.dat 档内第 1 行资料取代第 3 行资料。此时 , 用函数参数 h
与 x 来配合。其中 , 以函数参数 h 将第 1 资料存入 hold space ; 当第 3 行资料出现在Pattern
space , 以函数参数 x 交换 hold space 与 pattern space 的内容。如此 , 第 3 行资料就被第 1
资料替代
其命令列如下:sed -e ‘1h‘ -e ‘3x‘ input.dat
b、:label
函数参数 : 与函数参数 b 可在 sed script 内建立类似 BASIC 语言中 GOTO
指令的功能。其中 , 函数参数 : 建立标记;
函数参数 b 将下一个执行的指令 branch 到标记处执行。函数参数 : 与 b , 在
script file 内配合的情况如下 [address1,[address2]]b
[记号]
如果指令中函数参数 b 後没有记号 , 则 sed 将下一个执行的指令 branch 到
script file 的最後
例:将 input.dat 档内资料行的开头字母重覆印 40 次。假设 input.dat
档的内容如下:
A
B
C
说明: 用指令 b p1 与 :p1 构成执行增加字母的圈(loop) , 同时在字母出现 40
个时 , 也用指令 b 来跳出圈。下面就以档内第一行资料 "A" 为例 , 描述它如何连续多添加 39 个 "A"
在同一行:
用指令 s/A/AA/将 "A" 替换成 "AA".用指令 b p1 与 :p1
构成圈(loop) , 它目的使上述动作被反覆的执行。每执行一次圈 , 则资料行上的 "A" 就多出一个。例如 , 第一次圈资料行变成
"AA" , 第二次圈资料行变成 "AAA" ...
用指令 [ABC]\{40\}/b(解[15]) 来作为停止圈的条件。当资料行有连续 40 个 A
出现时 , 函数参数 b 将执行的指令跳到最後 , 停止对此行的编辑。同样 , 对其它资料行也如同上述的方式执行.
sed 命令列如下:
sed -e ‘{
:p1
/A/s/A/AA/
/B/s/B/BB/
/C/s/C/CC/
/[ABC]\{40\}/b
b p1
}‘ input.dat
t
基本上 , 函数参数 t 与 函数参数 b 的功能类似 , 除了在执行 t 的 branch 前
, 会先去测试其前的替换指令有没有执行替换成功外
其中 , 与函数参数 b 不同处在於 , 执行函数参数 t branch 时 ,
会先检查其前一个替换指令成功与否。如成功 , 则执行 branch ; 不成功 , 则不 branch ,
而继续执行下一个编辑指令
例将 input.dat 档中资料 A1 替换成 C1、C1 替换成 B1、B1 替换成
A1。input.dat 档的内容如下:
代号
B1
A1
B1
C1
A1
C1
说明 : input.dat 档中全部资料行只需要执行一次替换动作 , 但为避免资料被替换多次,
使每行资料替换一次後能立即用函数参数 t 跳离替换编辑
sed 命令列:
sed -e ‘{
s/A1/C1/
t
s/C1/B1/
t
s/B1/A1/
t
}‘ input.dat
{ commands }
组命令。作用是将多个命令用字符对( {} )括起来,形成一组命令。
\+ 与星号(*)相同,只是至少重复1次。是GNU的扩展功能
\? 与星号(*)相同,只是最多重复1次。是GNU的扩展功能
\{i\} 与星号(*)相同,只是重复指定的i次,i的值必须介于0至RE_DUP_MAX(含)之间。RE_
DUP_ MAX是POSIX定义的符号型常数,可通过getconf命令取得,最小值为255
\{i,j\} 与星号(*)相同,只是重复i至j次
\{i, \} 与星号(*)相同,只是至少重复i次
\(regexp\)
将regexp看作一个整体,用于:1、重复匹配中,如\(abc\)+匹配至少有一个整体abc的字符串;2、定义后向引用的子表达式
regexp1\|regexp2 用在相邻的正则表达式之间,表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的,一旦匹配就不再尝试下一个正则表达式。是GNU的扩展功能。
regexp1regexp2 匹配regexp1和regexp2的连接结果
GNU对转义字符的功能扩展
编号 转义字符 功能说明
1 \a 产生或匹配一个BEL字符,响铃作用,ASCII
7 。
2 \f 产生或匹配一个换页字符,ASCII
12 。
3 \n 产生或匹配一个换行字符,ASCII
10 。
4 \r 产生或匹配一个回车字符,ASCII
13 。
5 \t 产生或匹配一个水平Tab字符,ASCII
9 。
6 \v 产生或匹配一个垂直Tab字符,ASCII
11 。
7 \cX
产生或匹配Control-X,X是任意字符。精确结果是:若X是小写字母,就转成对应的大写字母。将X的ASCII值的第7bit位(从右向左)求反:\cz变为x1A,\c{变为x3B,\c;变为x7B
8 \dXXX 产生或匹配一个ASCII码是十进制XXX的字符。
9 \oXXX 产生或匹配一个ASCII码是八进制XXX的字符。
10 \xXX 产生或匹配一个ASCII码是十六进制XX的字符。
11 \w 匹配任意一个单词字符(字母、数字和下划线)。
12 \W 匹配任意一个非单词字符。
13 \b 匹配一个单词的边界符:字符的左边是一个单词字符,并且右边是一个非单词字符,反之亦然。???????
14 \B 匹配除单词边界符外所有字符:字符的左边和右边同时是单词字符或非单词字符。???????
15 \` 匹配模版空间的开头,在多行模式时,不同于字符^。???????
16 \’ 匹配模版空间的结束,在多行模式时,不同于字符$。??????
sed脚本中的地址形式,sed的地址用于sed命令的前面,表示只有符合指定地址条件的行才能执行后面的命令
1、NUMBER(单一匹配) 只匹配指定号行NUMBER的那一行
2、FIRST~STEP(递增匹配) GNU的扩展功能 匹配从起始行FIRST
(含)开始,以后行号每增加STEP的正整数倍,就是匹配行。比如要匹配所有奇数行就用1~2即可
3、$(尾行匹配) 匹配最后一个输入文件的最后一行;若有选项-i或-s则匹配每个输入文件的最后一行
4、/REGEXP/(正则表达式匹配) 匹配成功匹配正则表达式REGEXP的所有行。若REGEXP本身含有斜杠字符(/),则要用转义字
符反斜杠(\)进行转义:即\/,一个空的正则表达式(//),表示重复最近的一个非空的正则表达。空的正则表达式不能和调节器(I或M)一直使用,即
//I和//M是错误的
5、\%REGEXP%(正则表达式匹配) 和/REGEXP/功能一样。只是用字符%作为分隔符,而不是字符/,并且可用其他任意一个单字符作为分隔符。同样,若REGEXP本身含有指定的分隔符,要对它进行转义,
6、/REGEXP/I或\%REGEXP%I(I正则表达式匹配)
GNU的扩展功能 调节器I表示不区分大小,其余和上面第4、5项一样
7、/REGEXP/M或\%REGEXP%M(M正则表达式匹配)
GNU的扩展功能 调节器M使正则表达式REGEXP中的元字符^和$除了它们原含义的匹配功能外,元字符^和$还分别匹配:换行符后的空字符串和换行符前的空字符串。M是代表多行(Multi-line)的含义。而\`
和 \‘总是分别匹配缓冲的开始和结束
8、NONE(全匹配) 没有指定地址时,即匹配输入文件中的所有行。
9、FIRST,END(区间匹配) 匹配行号从起始行(含)到终止行(含)之间的所有行,若终止行数值小于等于起始行数值,则只匹配行号等于
起始行的一行文本,若终止行是一个正则表达式(REGEXP),则从起始行的下一行开始匹配这个正则表达式,一旦匹配(含匹配行)就结束,或直到输入数据
流结束(若有选项-i或-s时就是输入文件尾)
10、0,/REGEXP/(排除匹配) 这是唯一可以指定行号为0的形式,表示从文件第一行就开始尝试匹配指定的正则表达式,一旦匹配就结束
11、ADDR1,+N(连续匹配) 匹配ADDR1行及其后连续的N行
12、ADDR1,~ N(跳跃匹配) 匹配ADDR1行及其后行号是N的倍数的所有行。
13、!(反向匹配) 可以在以上12种地址形式后加一个惊叹号字符(!),表示反向匹配指定的地址,即匹配那些不在指定地址范围内的行
注意:
1、不允许指定地址的命令有(即所有行都会执行):
①、:label;②、#;③、}
2、最多能指定一个地址的命令有:
①、=;②、a\;③、i\;④、q ;⑤、Q;⑥、r;⑦、R
3、可指定多个地址的命令有:
①、{;②、b;③、t;④、T;⑤、c\;⑥、d;⑦、D;⑧、h;⑨、H;⑩、g;⑾、G;⑿、l;⒀、n;⒁、N;⒂、p;⒃、P;⒄、s;⒅、w;⒆、W;⒇、y
元字符表
元字符 含义说明
* 将*
前面的那一个正则表达式匹配的结果重复任意次(含0次)。前面的正则表达式可能是一个普通字符,或一个转义的元字符,或一个元字符句点( .
),或一个方括号表达式,或一个\(regexp\)。为了更好的可移植性,在要匹配星号( * )本身时,要用转义字符。
\+ 与星号(
* )相同,只是至少重复1次。是 GNU的扩展功能。
\? 与星号(
* )相同,只是最多重复1次。是 GNU的扩展功能。
\{i\} 与星号(
* )相同,只是重复指定的i次。i的值必须介于 0至 RE_DUP_MAX (含)之间。RE_ DUP_ MAX是
POSIX定义的符号型常数,可通过getconf命令取得,最小值为255。
\{i,j\} 与星号(
* )相同,只是重复i至j次。
\{i,
\} 与星号(
* )相同,只是至少重复i次。
\(regexp\) 将regexp看作一个整体,用于:1、上面第1到第
6项的重复匹配中,如\(abc\)+ 匹配至少有一个整体abc的字符串。2、定义后向引用的子表达式。
. 匹配任意单个字符。
^ 匹配模版空间(PATTERN
SPACE) 开始处的
NULL字符串,即任何出现在字符^后面的东西,必须是位于模版空间的开始处才能成功匹配。只有作为正则表达式的第一个字符或子表达式的第一个字符(在\(
或 \|
之后),字符^才有此作用,否则只是普通字符。为了更好的可移植性,不要在子表达式中使用此功能。
$ 同字符^类似,只是匹配的是模版空间结束处,只有作为正则表达式的最后一个字符或子表达式的最后一个字符(在\)
或 \|
之前),才有此作用,否则只是普通字符。为了更好的可移植性,不要在子表达式中使用此功能。
[list]、[
^list] 匹配方括号中的字符列表中的任意一个。1、第一个字符为脱字符(
^),则表示否定匹配,即匹配除字符列表中列出的那些字符以外的所有字符。 2、方括号中的连字符( -
):不是第一或最后一个字符时,只表示连续字符的范围(注意:范围会因
locale而有所不同,因此不具可移植性),否则作为普通字符进行匹配。3、要匹配右方括号( ]
)必须将它作为字符列表中的第一个字符。4、所有其他的元字符都看作为普通字符进行匹配。5、方括号表达式里可以含有POSIX定义的类字符
([..][==][::])。6、当系统没有完全遵守 POSIX标准时(即没设置 export
POSIXLY_CORRECT=true ),能识别方括号中含有的,且在
GNU对转义字符功能扩展中定义的转义功能,如\n表示换行符;否则不能识别,即\n表示两字符\和 n 。
regexp1\ | regexp2
用在相邻的正则表达式之间,表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的,一旦匹配就不在尝试下一个正则表达式。是
GNU的扩展功能。
regexp1regexp2 匹配regexp1和regexp2的连接结果。
\digit 匹配正则表达式前半部分定义的后向引用的第
digit个子表达式。digit为1至9的数字, 1为从左开始。
\n 匹配换行符。
\meta 将元字符meta转换成普通字符,以便匹配该字符本身,有$
、 * 、 . 、[ 、
\ 和 ^。
sed的3个编程命令
1、:Label
不允许有地址。无空格。
在分支命令的位置前指定标签Label,是没有操作指令的。
2、b [Label]
无条件地跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。
3、t [Label]
仅当分支条件符合时,或自从读取上一输入行后有过一次成功替换时,就跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。
GNU sed的9个扩展命令
1、e [Command]
允许将来自Shell命令的输出通过管道输入到模版空间。
①、没有指定Command时,在模版空间中被发现的Shell命令会被执行,并用执行结果取代模版空间中的数据,会自动去掉执行结果尾部的换行符。这类似于s命令的标志选项e功能。
②、指定Command时,就执行Command,并像r命令那样,将执行结果送到输出流;这个命令可以跨度多行,除了最后一行,每行要以一个反斜杠(\)结尾。
上面两种情况中,当被执行的命令包含NUL字符时,结果是没有定义的。
2、F
显示当前输入文件的文件名,会自动进行换行。
3、L n
在将来的版本中会删除此命令。
4、Q [Exit-code]
只接受单一匹配的sed地址。表示退出sed,不再处理任何命令或输入,一定不前会显示当前模版空间中的数据。若指定了退出代码,则返回它。
5、R Filename
在当前循环(即处理当前模版空间的过程)结束时,或当前循环没处理完,在读取下一输入行前时,将文件Filename的内容排成一行、读取并插入到输出流。注意,若文件Filename不能读取,就当作是一个空文件,是没有任何错误提示的。
在GNU sed中,文件可以是/dev/stdin,表示读取标准输入中一行内容。
6、T Label
仅当分支条件符合时,或自从读取上一输入行后没有过一次成功替换时,就跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。
7、v [Version]
用来验证是否支持GNU
sed的扩展功能,若不支持将使sed失败。同时,还可指定脚本要求的sed版本Version,如4.0.5,默认是4.0。
这命令会启用所有GNU的扩展功能,即使用环境变量POSIXLY_CORRECT取消也不行。
8、W Filename
将从模版空间的开始直到第一个换行符的数据写入文件Filename,其他的同命令w一样。
9、z
清空模版空间的内容,基本等同于命令s/.*//的作用,但比后者更有效、更可靠。
POSIX规定:元字符句点(.)是不能匹配不合法的多字节序列。所以,在大多数多字节地区(包括UTF-8地区),不能在脚本中实现可移植的清空sed缓冲区的方法。
其中“//D”是什么意思??"//"是简写,//代表使用上一次的正则
模式空间就是读入行所在的缓存,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的行
:lable
在脚本中标记一行,用于实现由b或t的控制转移。Label最多可以包含7个字符
=
=[address]=
将所寻址的行编写到标准输出,打印模式匹配的行号,使用格式
/pattern/=,整个文件都打印出来,并且匹配行打印了行号。如果只关心实际行号,使用 -e选项
a
[address]a
text
在与address匹配的每行后面追加text。如果text多于一行,必须用反斜杠将这些行前面的换行符“隐藏”起来。Text将被没有用这种方法隐藏
的第一个换行符结束。Text在模式空间中是不可用的并且后续的命令不能应用于它。当编辑命令的列表用完时,这个命令的结果将被输送到标准输出,而不管在
模式空间中的当前行发生了什么
b
[address1[,address2]]b[label] 无条件地将控制转移到脚本的其他位置的:label处。也就是说,label后面的命令是应用于当前行的下一个命令。如果没有指定label,
控制将一直到达脚本的末端,因此不再有命令作用于当前行
c
[address1[,address2]]c text
用text替代(改变)由地址选定的行。当指定的是一个行范围时,将所有的这些行作为一个组由text的一个副本来替代。每个text行后面的换行符必须用反斜杠将其转义,但最后一行除外。实际上,模式空间的内容被删除,因此后续的命令不能应用于它(或应用于text)
d
[address1[,address2]]d
从模式空间中删除行。因此行没有传递到标准输出。一个新的输入行被读取,并用脚本的第一个命令来编辑
D
[address1[,address2]]D
删除由命令N创建的多行模式空间中的一部分(直到嵌入的换行符),并且用脚本的第一条命令恢复编辑。如果这个命令使模式空间为空,那么将读取一个新的输入行,和执行了d命令一样
g
[address1[,address2]]g
将保持空间(参见h或H命令)中的内容复制到模式空间中,并将当前的内容清除
G
[address1[,address2]]G
将换行符后的保持空间(参见h或H命令)内容追加到模式空间。如果保持空间为空,则将换行符添加到模式空间
h
[address1[,address2]]h
将模式空间的内容复制到保存空间,即一个特殊的临时缓冲区。保存空间的当前内容被清除
H
[address1],address2]]H
将换行符和模式空间的内容追加到保持空间中,即使保持空间为空,这个命令也追加换行符
i
[address1]i
text 将text插入到每个和address匹配的行的前面
l
[address1[,address2]]l
列出模式空间的内容,将不可打印的字符表示为ASCII码。长的行被折行
n
[address1[,address2]]n
读取下一个输入行到模式空间。当前行被送到标准输出。新行成为当前行并递增行计数器。将控制转到n后面的命令,而不是恢复到脚本的顶部
N
[address1[,address2]]N
将下一个输入行追加到模式空间的内容之后;新添加的行与模式空间的当前内容用换行符分隔(这个命令用于实现跨两行的模式匹配。利用n来匹配嵌入的换行符,则可以实现多行匹配模式)
p
[address1[,address2]]p
打印所寻址的行。注意这将导致输出的重复,除非默认的输出用”#n”或”-n”命令行选项限制。常用于改变流控制(d,n,b)的命令之前并可能阻止当前行被输出
P
[address1[,address2]]P
打印由命令N创建的多行模式空间的第一部分(直接嵌入的换行符)。如果没有将N应用于某一行则和p相同
q
[address]q
当遇到address时退出。寻址的行首先被写到输出(如果没有限制默认输出),包括前面的a或r命令为它追加的文本
r
[address]r file
读取file的内容并追加到模式空间内容的后面。必须在r和文件名file之间保留一个空格
s
[address1[,address2]]s/pattern/replacement/[flags]
用replacement代替每个寻址的pattern。如果使用了模式地址,那么模式//表示最后指定的模式地址。可以指定下面的标志:
n
替代每个寻址的行的第n个/pattern/。N是1到512之间的任意数字,并且默认值为1
g
替代每个寻址的行的所有/pattern/,而不只是第一个
p
如果替换成功则打印这一行。如果成功进行了多个替换,将打印这个行的多个副本
w file
如果发生一次替换则将这行写入file。最多可以打开10个不同的file
replacement是一个字符串,用来替换与正则表达式匹配的内容.在replacement部分,只有下列字符有特殊含义:
&
用正则表达式匹配的内容进行替换
n
匹配第n个子串(n是一个数字),这个子串以前在pattern中用"("和")"指定
当在替换部分包含"与"符号(&),反斜杠()和替换命令的定界符时可用转义它们.另外,它用于转义换行符并创建多行replacement字符串
数字标志 s/pattern/replacememt/flag 如果flag是数字, 那么指定对一行上某个位置的匹配.如果没有数字标志,则替换命令只替换第一个匹配串,因此"1"可以被看作是默认的数字标志
替换元字符是反斜杠()、与符号(&)和n:
反斜杠一般用于转义其他的元字符,但是它在替换字符串中也用于包含换行符。
例如对于如下的行:column1(制表符)column2(制表符)column3(制表符)column4 使用如下替换语句:s/制表符//2 注意,在反斜杠的后面不允许有空格。这个脚本产生下面的结果:
column1(制表符)column2
column3(制表符)column4
"与"符号(&)作为元字符表示模式匹配的范围,不是被匹配的行.例如下面的命令:s/UNIX/s-2&s0/g 可以将输入行:on
the UNIX Operating System 替换成:on the s-2UNIXs0
Operating System。当正则表达式匹配单词的变化时,"与"符号特别有用.它允许指定一个可变的替换字符串.诸如"See
Section 1.4"或"See Section 12.9"的引用都应该出现在圆括号中,如"(See Section
12.9)".正则表达式可以匹配数字的不同组合,所以在替换字符串中可以使用"&"并括起所匹配的内容:s/See
Section
[1-9][0-9]*.[1-9][0-9]*/(&)/ 这里"与"符号用于在替换字符串中引用整个匹配内容
n元字符用于选择被匹配的字符串的任意独立部分,并且在替换字符串中回调它.在sed中转义的圆括号括住正则表达式的任意部分并且保存以备回调.一行最多允许保存9次.例如,当节号出现在交叉引用中时要表示为用粗体:s/(See
Section )([1-9][0-9]*.[1-9][0-9]*)/1fB2fp/
t
[address1[,address2]]t[label] 测试在寻址的行范围内是否成功执行了替换,如果是,则转移到有label标志的行(参见b和:)。如果没有给出label,控制将转移到脚本的底部
w
[address1[,address2]]w file
将模式空间的内容追加到file。这个动作是在遇到命令时发生而不是在输出模式空间内容时发生。必须在w和这个文件名之间保留一个空格。在脚
本中可以打开的最大文件数是10。如果文件不存在,这个命令将创建一个文件。如果文件存在,则每次执行脚本时将改写其内容,多重写入命令直接将输出写入到
同一个文件并追加到这个文件的末端
x
[address1[,address2]]x
交换模式空间和保持空间的内容
y
[address1[,address2]]y/abc/xyz/
按位置将字符串abc中的字符替换成字符串xyz中相应字符
在使用sed时,替换变量出现特殊字符,此时变量需要用"${var}"括起来,从shell向sed传值,要从命令行中向sed传值,值得注意的是用双引号,否则功能不执行.
"‘$var‘"
这种写法大家无需改变用‘括起awk程序的习惯.如:var="test" awk
‘BEGIN{print "‘$var‘"}‘
这种写法是双括号变为单括号的常量,传递给了awk.如果var中含空格,为了shell不把空格作为分格符,应如下使用:
var="this is a test"
awk ‘BEGIN{print "‘"$var"‘"}‘
‘"$var"‘
如果变量含空格,则变为‘""$var""‘较为可靠.
把括起awk程序的‘‘变为"",使用"$var"
如:
$var="this is a test"
awk ‘BEGIN{print "$var"}"
因为在""里$是特殊字符,而在‘‘里$是普通字符.
export 变量,使用ENVIRON["var"]形式
如:
$var="this is a test";export $var
awk ‘BEGIN{print ENVIRON["var"]}‘
也可以使用-v选项
如:
$var="this is a test"
awk -vnvar="$var" ‘{print nvar}‘
这样便把系统变量定义成了awk变量.
在awk中给系统变量附值
eval $(awk ‘BEGIN{print "a=ggg b=3"}‘)
eval $(grep -v ‘#‘ "$CONFFILE" | awk ‘BEGIN{FS="|"}
NR=="‘$var_list‘"{printf("HOST=\"%s\" MAX=\"%s\" EMAILLIST=\"%s\"
PHONE=\"%s\"\n",$1,$2,$3,$4)}‘)
倒序文件 sed -e ‘1!G;h;$!d‘ a.txt >
b.txt
把保留空间(临时缓冲区)的内容附接到当前行的模式空间,删除当前行模式空间,如此往复,直到最后一行,到最后一行的时候不删除当前模式空间,最后输出模式空间。上述sed命令‘1!G;h;$!d‘,用分号隔开三个子命令G,
h,
d,应用于每一行的分析,G表示把缓冲区内容附接到当前模式空间中,h表示将模式空间的内容保存到缓冲区中,d表示删除模式空间。
去掉<xx>abcdefg</xxx>内容两边的括号,如果内容之间有换行,又该如何办?
*没有换行的情况:
echo
"<xx>abcdefg</xxx>"
| sed
‘s/\(<.*>\)\(.*\)\(<.*>\)/\2/‘
echo
"<xx>abcdefg</xxx>"
| sed
‘s/<[^>]*>//g‘
*内容中有换行的情况
#cat test.sed
#!/bin/sed -f
:a
/<[^>]*$/{
N
ba
}
s/<[^>]*>//g
删除配置文件中#号注释的行
sed ‘s#\#.*##‘ file.conf >
file.new.conf
sed -i ‘s#\#.*##‘ file.conf
grep -v "#" file.conf
删除配置文件中//号注释的行
sed ‘s#//.*##‘ file.conf >
file.new.conf
grep -v ‘^//‘ file.conf
单引号内所有元字符都失去特殊含义(包括\),双引号内除了变量域($)和命令域(‘)以外的元字符都失去特殊含义,一般使用双引号引用.花括号{}被用来区分变量名和周围的文本:echo ${file} and $file1 寻找变量file,file1.‘‘命令替代的格式:反引号来环绕一个命令像‘cmd‘,和$(cmmand)是等价的:echo ${ls} = echo ‘ls‘ 执行此选项中的命令
对ip地址进行替换和修改
#在sed中使用变量
aa=0
bb=77
sed
"1,2{s/\([0-9]\{1,3\}\.[0-9]\{1,3\}\.\)$aa\(\.[0-9]\{1,3\}\)/\1$bb\2/}"
file
其中的中间()号中的是对IP地址的匹配。注意其IP地址的正则表达的匹配方式。而前面的1,2表示需要处理的起止行数
删除文件中的后两行
sed -i "$d" file | sed -i "$d" file 或 sed
‘N;$d;P;D‘
匹配一行中的或关系的多个字符串
awk ‘/string1/||/string2/ { print $0 }‘
file 或 sed -n
"/string1\|string2/p" file
取特定数目倍数的行
nl filename | awk
‘(NR-3)%3==0‘ 取filename中3,2×3,3×3,3×4等行,当然也可以把逻辑变换以下,取任意于行数相关的行。
选出以数字开头的行,该行的数字要大于10位
sed -n ‘/^[0-9]\{10,\}/p‘ ff
把/usr/local:替换成/usr:
sed -e ‘s/\(\/usr\).*/\1:/g‘ file
sed -e ‘s/\/usr/local:/\/usr:/g‘ file
sed -e ‘s:/usr/local:/usr:g‘ file
awk -F‘/‘ ‘{print "/"$2":"}‘
有文件d7如下,请把第三行的7全部变成8
20080602/1/6/2
20080602/2/7/3
20080602/3/7/2
20080602/4/6/3
sed -e ‘s/\(.*\/.*\/\)7\(\/.*\)/\18\2/‘
file
awk -F‘/‘ ‘{if($3==7) {$3=8} print
$1"/"$2"/"$3"/"$4}‘ file
awk -F "/" ‘{OFS="/"}{if($3==7) $3=8; print $0}‘
file
取一行中的特定段的字符的方法总结
1) sed
2) awk
3) cut
4) grep
*)删除文件中的前10000行
1) sed ‘1,10000d‘ file
2) awk ‘NR>10000‘ file
*)删除含有特定字符串1到特定字符串2的行
1) sed ‘/str1/,/str2/d‘ file
把文件中的所有行末尾的\n都去掉;把文件组成一行
sed ‘{:a;N;s/\n/ /;ba}‘ filename
这是一个循环,用N来读取下一行并追加到模式空间中;用标签:a和跳转b来循环这个过程
每隔两行进行合并
sed ‘{N;s/\n/ /}‘ filename
把文中的单词(以,号隔开)的格式化成,每行一个(用\n替换掉,即可)
sed ‘s/,/\n/g‘ filename
替换一列
11 22 33
11 22 33
替换第一列为55
sed ‘s/^11/55/‘ file
替换第2列为66
sed ‘s/\(.*\) .* \(.*\)/\1 66 \2/‘ file
删除空白(由tab和空格或只有\n的行组成)行
sed ‘/^[ \t\n]*$/d‘ file
sed ‘/^[[:space:]]*$/d‘
替换每行的第2个字符到第6个字符为*号
sed ‘s/\(^.\).\{5\}\(.*\)/\1*****\2/‘
sed ‘{s/.3;s/.5;s/./‘
将每一行拖尾的“空白字符”(空格,制表符)删除
sed ‘s/[ \t]*$//‘
将每一行中的前导和拖尾的空白字符删除
sed ‘s/^[ \t]*//;s/[ \t]*$//‘
在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
sed
‘s/^/
/‘
以79个字符为宽度,将所有文本右对齐
sed -e :a -e ‘s/^.\{1,78\}$/
&/;ta‘ #78个字符外加最后的一个空格
以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前头和后头都填充了空格。
在方法2中,在居中文本的过程中只在文本的前面填充空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格
sed -e :a -e ‘s/^.\{1,77\}$/
& /;ta‘
sed -e :a -e ‘s/^.\{1,77\}$/
&/;ta‘ -e ‘s/\( *\)\1/\1/‘
在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
sed ‘s/foo/bar/‘
sed ‘s/foo/bar/4‘
sed ‘s/foo/bar/g‘
sed ‘s/\(.*\)foo\(.*foo\)/\1bar\2/‘
sed ‘s/\(.*\)foo/\1bar/‘
只在行中出现字串“baz”的情况下将“foo”替换成“bar”
sed ‘/baz/s/foo/bar/g‘
将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
sed ‘/baz/!s/foo/bar/g‘
不管是“scarlet”“ruby”还是“puce”,一律换成“red”
sed
‘s/scarlet/red/g;s/ruby/red/g;s/puce/red/g‘ #对多数的sed都有效
gsed
‘s/scarlet\|ruby\|puce/red/g‘ #只对GNU
sed有效
倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)(由于某些原因,使用下面命令时HHsed
v1.5会将文件中的空行删除)
sed ‘1!G;h;$!d‘
sed -n ‘1!G;h;$p‘
将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
sed
‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//‘
将每两行连接成一行(类似“paste”)
sed ‘$!N;s/\n/ /‘
如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾,并去掉原来行尾的反斜杠
sed -e :a -e ‘/\\$/N; s/\\\n//; ta‘
如果当前行以等号开头,将当前行并到上一行末尾,并以单个空格代替原来行头的“=”
sed -e :a -e ‘$!N;s/\n=/ /;ta‘ -e ‘P;D‘
为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
gsed
‘:a;s/\B[0-9]\{3\}\>/,&/;ta‘
sed -e :a -e
‘s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta‘
为带有小数点和负号的数值增加逗号分隔符(GNU sed)
gsed -r
‘:a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta‘
在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
gsed ‘0~5G‘
sed ‘n;n;n;n;G;‘
选择性地显示特定行:
#显示文件中的前10行 (模拟“head”的行为)
sed 10q
#显示文件中的第一行 (模拟“head -1”命令)
sed q
#显示文件中的最后10行 (模拟“tail”)
sed -e :a -e ‘$q;N;11,$D;ba‘
#显示文件中的最后2行(模拟“tail -2”命令)
sed ‘$!N;$!D‘
#显示文件中的最后一行(模拟“tail -1”)
sed ‘$!d‘
sed -n ‘$p‘
显示文件中的倒数第二行
sed -e ‘$!{h;d;}‘ -e
x
#当文件中只有一行时,输入空行
sed -e ‘1{$q;}‘ -e ‘$!{h;d;}‘ -e
x #当文件中只有一行时,显示该行
sed -e ‘1{$d;}‘ -e ‘$!{h;d;}‘ -e
x #当文件中只有一行时,不输出
只显示匹配正则表达式的行(模拟“grep”)
sed -n ‘/regexp/p‘
sed ‘/regexp/!d‘
只显示“不”匹配正则表达式的行(模拟“grep -v”)
sed -n ‘/regexp/!p‘
sed ‘/regexp/d‘
查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
sed -n ‘/regexp/{g;1!p;};h‘
查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
sed -n ‘/regexp/{n;p;}‘
显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1
-B1”)
sed -n -e ‘/regexp/{=;x;1!p;g;$!N;p;D;}‘ -e h
显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
sed ‘/AAA/!d; /BBB/!d; /CCC/!d‘
显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
sed ‘/AAA.*BBB.*CCC/!d‘
显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e
d #多数sed
gsed
‘/AAA\|BBB\|CCC/!d‘ #对GNU
sed有效
显示包含“AAA”的段落 (段落间以空行分隔),HHsed v1.5
必须在“x;”后加入“G;”,接下来的3个脚本都是这样
sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;‘
显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
sed -e ‘/./{H;$!d;}‘ -e
‘x;/AAA/!d;/BBB/!d;/CCC/!d‘
显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/b‘ -e ‘/BBB/b‘ -e
‘/CCC/b‘ -e d
gsed
‘/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d‘
#只对GNU sed有效
显示包含65个或以上字符的行
sed -n ‘/^.\{65\}/p‘
显示包含65个以下字符的行
sed -n ‘/^.\{65\}/!p‘
sed ‘/^.\{65\}/d‘
显示部分文本——从包含正则表达式的行开始到最后一行结束
sed -n ‘/regexp/,$p‘
显示部分文本——指定行号范围(从第8至第12行,含8和12行)
sed -n ‘8,12p‘
sed ‘8,12!d‘
显示第52行
sed -n ‘52p‘
sed ‘52!d‘
sed ‘52q;d‘
从第3行开始,每7行显示一次
gsed -n
‘3~7p‘
#只对GNU sed有效
sed -n
‘3,${p;n;n;n;n;n;n;}‘
#其他sed
显示两个正则表达式之间的文本(包含)
sed -n
‘/Iowa/,/Montana/p‘
#区分大小写方式
显示通篇文档,除了两个正则表达式之间的内容
sed ‘/Iowa/,/Montana/d‘
删除文件中相邻的重复行(模拟“uniq”),只保留重复行中的第一行,其他行删除
sed ‘$!N; /^\(.*\)\n\1$/!P; D‘
删除文件中的重复行,不管有无相邻,注意hold space所能支持的缓存大小,或者使用GNU sed
sed -n ‘G;
s/\n/&&/; /^\([ -~]*\n\).*\n\1/d;
s/\n//; h; P‘
删除除重复行外的所有行(模拟“uniq -d”)
sed ‘$!N; s/^\(.*\)\n\1$/\1/; t; D‘
删除文件中开头的10行
sed ‘1,10d‘
删除文件中的最后一行
sed ‘$d‘
删除文件中的最后两行
sed ‘N;$!P;$!D;$d‘
删除文件中的最后10行
sed -e :a -e ‘$d;N;2,10ba‘ -e ‘P;D‘
sed -n -e :a -e ‘1,10!{P;N;D;};N;ba‘
删除8的倍数行
gsed
‘0~8d‘
#只对GNU sed有效
sed
‘n;n;n;n;n;n;n;d;‘
#其他sed
删除匹配式样的行
sed ‘/pattern/d‘
删除文件中的所有空行(与“grep ‘.‘ ”效果相同)
sed ‘/^$/d‘
sed ‘/./!d‘
只保留多个相邻空行的第一行,并且删除文件顶部和尾部的空行,(模拟“cat -s”)
sed
‘/./,/^$/!d‘
#删除文件顶部的空行,允许尾部保留一空行
sed
‘/^$/N;/\n$/D‘
#允许顶部保留一空行,尾部不留空行
只保留多个相邻空行的前两行
sed ‘/^$/N;/\n$/N;//D‘
删除文件顶部的所有空行
sed ‘/./,$!d‘
删除文件尾部的所有空行
sed -e :a -e ‘/^\n*$/{$d;N;ba‘ -e ‘}‘
sed -e :a -e ‘/^\n*$/N;/\n$/ba‘
删除每个段落的最后一行
sed -n ‘/^$/{p;h;};/./{x;/./p;}‘
移除手册页(man page)中的nroff标记。在Unix System V或bash
shell下使用‘echo‘命令时可能需要加上 -e 选项
sed "s/.`echo
\\\b`//g"
#外层的双括号是必须的(Unix环境)
sed
‘s/.^H//g‘
#在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
sed
‘s/.\x08//g‘
#sed 1.5,GNU sed,ssed所使用的十六进制的表示方法
提取新闻组或 e-mail 的邮件头
sed
‘/^$/q‘
#删除第一行空行后的所有内容
提取新闻组或 e-mail 的正文部分
sed
‘1,/^$/d‘
#删除第一行空行之前的所有内容
从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样
sed ‘/^Subject: */!d; s///;q‘
从邮件头获得回复地址
sed ‘/^Reply-To:/q; /^From:/h; /./d;g;q‘
获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除
sed ‘s/ *(.*)//; s/>.*//;
s/.*[:<] *//‘
在每一行开头加上一个尖括号和空格(引用信息)
sed ‘s/^/> /‘
将每一行开头处的尖括号和空格删除(解除引用)
sed ‘s/^> //‘
移除大部分的HTML标签(包括跨行标签)
sed -e :a -e
‘s/<[^>]*>//g;/</N;//ba‘
将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分,文件必须以特定顺序传给sed,下面第一种版本的脚本可以直接在命令行下输入,第二种版本则可以放入一个带执行权限的shell脚本中
sed ‘/^end/,/^begin/d‘ file1 file2 ... fileX |
uudecode #vers. 1
sed ‘/^end/,/^begin/d‘ "$@" |
uudecode
#vers. 2
将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU
sed使用字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以用其他未在文件中使用的字符来代替它。
sed ‘/./{H;d;};x;s/\n/={NL}=/g‘ file | sort | sed
‘1s/={NL}=//;s/={NL}=/\n/g‘
gsed ‘/./{H;d};x;y/\n/\v/‘ file | sort | sed
‘1s/\v//;y/\v/\n/‘
分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件命名为与原来相同的名字(只是扩展名不同)(DOS环境:“dir
/b”#显示不带路径的文件名)
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1
\1.TXT/" >>zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1
\1.TXT/" >>zipup.bat
‘s/\.$//g’
删除以句点结尾行
‘-e
/abcd/d’
删除包含abcd的行
‘s/[][][]*/[]/g’
删除一个以上空格,用一个空格代替
‘s/^[][]*//g’
删除行首空格
‘s/\.[][]*/[]/g’
删除句点后跟两个或更多空格,代之以一个空格
‘/^$/d’
删除空行
‘s/^.//g’
删除第一个字符
‘s/COL\(...\)//g’
删除紧跟COL的后三个字母
‘s/^\///g’
从路径中删除第一个\
‘s/[]/[]//g’
删除所有空格并用tab键替代
‘S/^[]//g’
删除行首所有tab键
‘s/[]*//g’
删除所有tab键
sed常用操作
删除配置文件中#号注释行
sed ‘ s#\#.
:e## ‘
_
.conf
>
~
.new.conf
删除配置文件中//号注释行
sed ‘s#//.*##‘ file.conf >
file.new.conf
删除无内容空行
sed ‘/^$/d‘ file.conf >
file.new.conf
删除由空格和Tab而成的空行
sed ‘/^[[:space:]]*$/d‘ file.conf
> file.new.conf
sed—i可以直接写入不用>
grep对应的用法
删除配置文件中#号注释行
sed
‘s#\#.*##‘ file.conf > file.new.conf
sed -i
‘s#\#.*##‘ file.conf
grep -v "#"
file.conf
删除配置文件中//号注释行
sed
‘s#//.*##‘ file.conf > file.new.conf
grep
-v ‘^//‘ file.conf
删除无内容空行
sed ‘/^$/d‘ file.conf >
file.new.conf
grep -v
‘^$‘ file.conf
删除由空格和Tab而成的
sed ‘/^[[ : space: ] ]*$/d ‘ file.conf
> file.new.conf
grep [ : space : ] file.conf
利用sed取行/替换
单引号、双引号、括号、花括号及反引号
单引号内所有元字符都失去特殊含义(包括\)双引号内除了变量域($)和命令域(‘)以外的元字符都失去特殊含义,所以一般使用双引号引用
花括号{}被用来区分变量名和周围的文本:echo ${f.le)and
$filel寻找变量file,filel
‘‘命令替代的格式:反引号来环绕一个命令象‘cmd‘,它和$(command)是等价的echo
${ls)=echo \ls‘,‘执行此选项中的命令‘
取行
sed—n“3”p file取第3行
sed—n“1,3“p file取第1到3行
sed—n“1,$“p file取第1到最后一行
sed—n“1,$num”p file取第1至0 num行
sed—n“\$p“file取最后1行
sed—e‘1 1Gj hj$!d‘file倒过来显示
sed附加/替换
sed “/xmdh/a\daoyou“
file 把含有xmdh的行的结尾附加daoyou(有换行)
sed ‘s/$/
daoyou/’file 把每行的结尾附加daoyou(在同一行)
sed ’/test/s/$/
daoyou/‘ file把包含test行的结尾附加daoyou(在同一行)
sed ‘10s/$/
daoyou/’file 把第10行的结尾附加daoyou(在同一行)
sed "s/xmdh/daoyou/g"
file 把xmdh替换成daoyou
sed "s/xmdh/daoyou/;G"
file 把xmdh替换成daoyou并增加一个换行
cat userlog | sed —n ’/xmdh/w
test.txt’ 查看含有xmdh并写入test .txt中
搜索
vi file后:
/\<daoyou\>/
显示行号
awk ‘/dhshunde/{print NR,$O}‘
userlog 或 grep -n dhshunde
userlog显示含有dhshunde的行号及内容
cat userlog lsed—n‘/erptest/=’
显示含有erptest的行号
cat userlog lsed—n’/xmdh/p‘ |
sed—n’$p’ 显示包含xmdh的最后一行
awk中使用变量
/bin/cat /etc/ppp/chap-secretslgrep $5lawk
‘{print
logoutt ime " \t " , -‘ u sername : -‘ $1 -‘ \t
-‘ , " logout " -‘ \t -‘ , -‘ data : -‘ data size}
logouttime=" - /bin/date- "datasize=
"$size"
>>$pptplogdirectory/userlog (注:
size前面已经有定义)
find的用法
注:find命令将所有匹配到的文件一起传递给exec执行,而xargs命令每次只获取一部分文件而不是全部所以exec有长度限制,文件不能太多,否则会产生溢出错误,而xargs别没有
find.-mtime -1
-print 跟现在小于1天修改的文件
find.-perm 755
-print 显示具有755属性的文件
find.-size +1000000c
-print 查找大于1M的文件
find.-type f -exec ls —l {}
\;查找文件并列表显示(注:{}与\之间有空格,最后有;)
find.-type f -exec rm {}
\; 查找文件并删除
find.-type f -print | xargs ls
-l 查看文件并列表显示
find / \(-perm -4000 -o -perm -2000\)-type f-
print查找SUID和SGID文件
向登录终端用户发送消息
echo "hello i am jiangdaoyou" |tee /dev/pts/2
(tty可以查看自己的终端号),等同于:write root pts/2然后输入:hello i am jiangdaoyou
然后Ctrl+D结束
awk之BEGIN和END
即在文件头增加列名:
cat userlog lawk ‘BEGIN{print "Time
username\n----
一“)j{print$4J$7)
Time
username
15:19: 28 username:xmdh
15: 20: 00 username: xmdh
即在文件头增加列名:
cat userlog lawk ‘BEGIN{print "Time
username\n----
一“);{print$4,$7)‘
Time username
截取/转化字符
echo "200604211031" | cut
-c9-12 得到 1031
cat test.ok |tr ‘arp‘ ‘rpm‘ 把
arp转为 rpm
求平均值
vmstat 1 4 |awk ‘{print $4}‘
|grep -o ‘[0-9]*‘ |sed ‘s/,//g‘ |awk
‘{total=total+$l; if(NR%4==0)
{print total/4}} ‘ 成如下方法:
vmstat 1 4lawk
‘NR>2{sum+=$4}END{print sum/4}‘
循环
ls | for file in *;do echo "rpm -ivh"
$file;done
ls | for file in $(ls *.rpm);do echo "rpm -ivh"
$file;done
在每一行后面增加一空行
sed G
将原来的所有空行删除并在每一行后面增加一空行。这样在输出的文本中每一行后面将有且只有一空行。
sed ‘/^$/d;G‘
在每一行后面增加两行空行
sed ‘G;G‘
将第一个脚本所产生的所有空行删除(即删除所有偶数行)
sed ‘n;d‘
在匹配式样“regex”的行之前插入一空行
sed ‘/regex/{x;p;x;}‘
在匹配式样“regex”的行之后插入一空行
sed ‘/regex/G‘
在匹配式样“regex”的行之前和之后各插入一空行
sed ‘/regex/{x;p;x;G;}‘
为文件中的每一行进行编号(简单的左对齐方式)。这里使用了“制表符”(tab,见本文末尾关于‘\t‘的用法的描述)而不是空格来对齐边缘。
sed = filename | sed ‘N;s/\n/\t/‘
对文件中的所有行编号(行号在左,文字右端对齐)。
sed = filename | sed ‘N;
s/^/
/; s/ *\(.\{6,\}\)\n/\1 /‘
对文件中的所有行编号,但只显示非空白行的行号。
sed ‘/./=‘ filename | sed ‘/./N; s/\n/ /‘
计算行数 (模拟 "wc -l")
sed -n ‘$=‘
Unix环境:转换DOS的新行符(CR/LF)为Unix格式。
sed
‘s/.$//‘
# 假设所有行以CR/LF结束
sed
‘s/^M$//‘
# 在bash/tcsh中,将按Ctrl-M改为按Ctrl-V
sed
‘s/\x0D$//‘
# ssed、gsed 3.02.80,及更高版本
Unix环境:转换Unix的新行符(LF)为DOS格式。
sed "s/$/`echo -e
\\\r`/"
# 在ksh下所使用的命令
sed ‘s/$‘"/`echo
\\\r`/"
# 在bash下所使用的命令
sed "s/$/`echo
\\\r`/"
# 在zsh下所使用的命令
sed
‘s/$/\r/‘
# gsed 3.02.80 及更高版本
DOS环境:转换Unix新行符(LF)为DOS格式。
sed
"s/$//"
# 方法 1
sed -n
p
# 方法 2
DOS环境:转换DOS新行符(CR/LF)为Unix格式。
下面的脚本只对UnxUtils sed 4.0.7
及更高版本有效。要识别UnxUtils版本的sed可以通过其特有的“--text”选项。你可以使用帮助选项(“--help”)看其中有无一个
“--text”项以此来判断所使用的是否是UnxUtils版本。其它DOS版本的的sed则无法进行这一转换。但可以用“tr”来实现这一转换。
sed "s/\r//" infile
>outfile
# UnxUtils sed v4.0.7 或更高版本
tr -d \r <infile
>outfile
# GNU tr 1.22 或更高版本
将每一行前导的“空白字符”(空格,制表符)删除
使之左对齐
sed ‘s/^[
\t]*//‘
# 见本文末尾关于‘\t‘用法的描述
将每一行拖尾的“空白字符”(空格,制表符)删除
sed ‘s/[
\t]*$//‘
# 见本文末尾关于‘\t‘用法的描述
将每一行中的前导和拖尾的空白字符删除
sed ‘s/^[ \t]*//;s/[ \t]*$//‘
在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
sed
‘s/^/
/‘
以79个字符为宽度,将所有文本右对齐
sed -e :a -e ‘s/^.\{1,78\}$/
&/;ta‘ # 78个字符外加最后的一个空格
以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前头和后头都填充了空格。
在方法2中,在居中文本的过程中只在文本的前面填充空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格。
sed -e :a -e ‘s/^.\{1,77\}$/
&
/;ta‘
# 方法1
sed -e :a -e ‘s/^.\{1,77\}$/
&/;ta‘ -e ‘s/\( *\)\1/\1/‘ #
方法2
在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
sed
‘s/foo/bar/‘
# 只替换每一行中的第一个“foo”字串
sed
‘s/foo/bar/4‘
# 只替换每一行中的第四个“foo”字串
sed
‘s/foo/bar/g‘
# 将每一行中的所有“foo”都换成“bar”
sed ‘s/\(.*\)foo\(.*foo\)/\1bar\2/‘ #
替换倒数第二个“foo”
sed
‘s/\(.*\)foo/\1bar/‘
# 替换最后一个“foo”
只在行中出现字串“baz”的情况下将“foo”替换成“bar”
sed ‘/baz/s/foo/bar/g‘
将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
sed ‘/baz/!s/foo/bar/g‘
不管是“scarlet”“ruby”还是“puce”,一律换成“red”
sed
‘s/scarlet/red/g;s/ruby/red/g;s/puce/red/g‘
#对多数的sed都有效
gsed
‘s/scarlet\|ruby\|puce/red/g‘
# 只对GNU sed有效
倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)。由于某些原因,使用下面命令时HHsed
v1.5会将文件中的空行删除
sed
‘1!G;h;$!d‘
# 方法1
sed -n
‘1!G;h;$p‘
# 方法2
将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
sed
‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//‘
将每两行连接成一行(类似“paste”)
sed ‘$!N;s/\n/ /‘
如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾并去掉原来行尾的反斜杠
sed -e :a -e ‘/\\$/N; s/\\\n//; ta‘
如果当前行以等号开头,将当前行并到上一行末尾并以单个空格代替原来行头的“=”
sed -e :a -e ‘$!N;s/\n=/ /;ta‘ -e ‘P;D‘
为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
gsed
‘:a;s/\B[0-9]\{3\}\>/,&/;ta‘
# GNU sed
sed -e :a -e
‘s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta‘ #
其他sed
为带有小数点和负号的数值增加逗号分隔符(GNU sed)
gsed -r
‘:a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta‘
在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
gsed
‘0~5G‘
# 只对GNU sed有效
sed
‘n;n;n;n;G;‘
# 其他sed
显示文件中的前10行 (模拟“head”的行为)
sed 10q
显示文件中的第一行 (模拟“head -1”命令)
sed q
显示文件中的最后10行 (模拟“tail”)
sed -e :a -e ‘$q;N;11,$D;ba‘
显示文件中的最后2行(模拟“tail -2”命令)
sed ‘$!N;$!D‘
显示文件中的最后一行(模拟“tail -1”)
sed
‘$!d‘
# 方法1
sed -n
‘$p‘
# 方法2
显示文件中的倒数第二行
sed -e ‘$!{h;d;}‘ -e
x
# 当文件中只有一行时,输入空行
sed -e ‘1{$q;}‘ -e ‘$!{h;d;}‘ -e
x # 当文件中只有一行时,显示该行
sed -e ‘1{$d;}‘ -e ‘$!{h;d;}‘ -e
x # 当文件中只有一行时,不输出
只显示匹配正则表达式的行(模拟“grep”)
sed -n
‘/regexp/p‘
# 方法1
sed
‘/regexp/!d‘
# 方法2
只显示“不”匹配正则表达式的行(模拟“grep -v”)
sed -n
‘/regexp/!p‘
# 方法1,与前面的命令相对应
sed
‘/regexp/d‘
# 方法2,类似的语法
查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
sed -n ‘/regexp/{g;1!p;};h‘
查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
sed -n ‘/regexp/{n;p;}‘
显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1
-B1”)
sed -n -e ‘/regexp/{=;x;1!p;g;$!N;p;D;}‘ -e h
显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
sed ‘/AAA/!d; /BBB/!d; /CCC/!d‘
# 字串的次序不影响结果
显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
sed ‘/AAA.*BBB.*CCC/!d‘
显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e
d #
多数sed
gsed
‘/AAA\|BBB\|CCC/!d‘
# 对GNU sed有效
显示包含“AAA”的段落 (段落间以空行分隔)
HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样
sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;‘
显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
sed -e ‘/./{H;$!d;}‘ -e
‘x;/AAA/!d;/BBB/!d;/CCC/!d‘
显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/b‘ -e ‘/BBB/b‘ -e
‘/CCC/b‘ -e d
gsed
‘/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d‘
# 只对GNU sed有效
显示包含65个或以上字符的行
sed -n ‘/^.\{65\}/p‘
显示包含65个以下字符的行
sed -n
‘/^.\{65\}/!p‘
# 方法1,与上面的脚本相对应
sed
‘/^.\{65\}/d‘
# 方法2,更简便一点的方法
显示部分文本——从包含正则表达式的行开始到最后一行结束
sed -n ‘/regexp/,$p‘
显示部分文本——指定行号范围(从第8至第12行,含8和12行)
sed -n
‘8,12p‘
# 方法1
sed
‘8,12!d‘
# 方法2
显示第52行
sed -n
‘52p‘
# 方法1
sed
‘52!d‘
# 方法2
sed
‘52q;d‘
# 方法3, 处理大文件时更有效率
从第3行开始,每7行显示一次
gsed -n
‘3~7p‘
# 只对GNU sed有效
sed -n
‘3,${p;n;n;n;n;n;n;}‘
# 其他sed
显示两个正则表达式之间的文本(包含)
sed -n
‘/Iowa/,/Montana/p‘
# 区分大小写方式
显示通篇文档,除了两个正则表达式之间的内容
sed ‘/Iowa/,/Montana/d‘
删除文件中相邻的重复行(模拟“uniq”)只保留重复行中的第一行,其他行删除
sed ‘$!N; /^\(.*\)\n\1$/!P; D‘
删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存大小,或者使用GNU sed。
sed -n ‘G;
s/\n/&&/; /^\([ -~]*\n\).*\n\1/d;
s/\n//; h; P‘
删除除重复行外的所有行(模拟“uniq -d”)
sed ‘$!N; s/^\(.*\)\n\1$/\1/; t; D‘
删除文件中开头的10行
sed ‘1,10d‘
删除文件中的最后一行
sed ‘$d‘
删除文件中的最后两行
sed ‘N;$!P;$!D;$d‘
删除文件中的最后10行
sed -e :a -e ‘$d;N;2,10ba‘ -e
‘P;D‘ # 方法1
sed -n -e :a -e
‘1,10!{P;N;D;};N;ba‘ # 方法2
删除8的倍数行
gsed
‘0~8d‘
# 只对GNU sed有效
sed
‘n;n;n;n;n;n;n;d;‘
# 其他sed
删除匹配式样的行
sed
‘/pattern/d‘
# 删除含pattern的行。当然pattern可以换成任何有效的正则表达式
删除文件中的所有空行(与“grep ‘.‘ ”效果相同)
sed
‘/^$/d‘
# 方法1
sed
‘/./!d‘
# 方法2
只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。(模拟“cat -s”)
sed
‘/./,/^$/!d‘
#方法1,删除文件顶部的空行,允许尾部保留一空行
sed
‘/^$/N;/\n$/D‘
#方法2,允许顶部保留一空行,尾部不留空行
只保留多个相邻空行的前两行。
sed ‘/^$/N;/\n$/N;//D‘
删除文件顶部的所有空行
sed ‘/./,$!d‘
删除文件尾部的所有空行
sed -e :a -e ‘/^\n*$/{$d;N;ba‘ -e
‘}‘ # 对所有sed有效
sed -e :a -e
‘/^\n*$/N;/\n$/ba‘
# 同上,但只对 gsed 3.02.*有效
删除每个段落的最后一行
sed -n ‘/^$/{p;h;};/./{x;/./p;}‘
移除手册页(man page)中的nroff标记。在Unix System V或bash
shell下使用‘echo‘命令时可能需要加上 -e 选项。
sed "s/.`echo
\\\b`//g"
# 外层的双括号是必须的(Unix环境)
sed
‘s/.^H//g‘
# 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
sed
‘s/.\x08//g‘
# sed 1.5,GNU sed,ssed所使用的十六进制的表示方法
提取新闻组或 e-mail 的邮件头
sed
‘/^$/q‘
# 删除第一行空行后的所有内容
提取新闻组或 e-mail 的正文部分
sed
‘1,/^$/d‘
# 删除第一行空行之前的所有内容
从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样
sed ‘/^Subject: */!d; s///;q‘
从邮件头获得回复地址
sed ‘/^Reply-To:/q; /^From:/h; /./d;g;q‘
获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除。(见上一脚本)
sed ‘s/ *(.*)//; s/>.*//;
s/.*[:<] *//‘
在每一行开头加上一个尖括号和空格(引用信息)
sed ‘s/^/> /‘
将每一行开头处的尖括号和空格删除(解除引用)
sed ‘s/^> //‘
移除大部分的HTML标签(包括跨行标签)
sed -e :a -e
‘s/<[^>]*>//g;/</N;//ba‘
将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分。文件必须以特定顺序传给sed。下面第一种版本的脚本可以直接在命令行下输入;第二种版本则可以放入一个带执行权限的shell脚本中。(由Rahul
Dhesi的一个脚本修改而来。)
sed ‘/^end/,/^begin/d‘ file1 file2 ... fileX |
uudecode # vers. 1
sed ‘/^end/,/^begin/d‘ "$@" |
uudecode
# vers. 2
将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU
sed使用字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以用其他未在文件中使用的字符来代替它。
sed ‘/./{H;d;};x;s/\n/={NL}=/g‘ file | sort | sed
‘1s/={NL}=//;s/={NL}=/\n/g‘
gsed ‘/./{H;d};x;y/\n/\v/‘ file | sort | sed
‘1s/\v//;y/\v/\n/‘
分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件命名为与原来相同的名字(只是扩展名不同)。(DOS环境:“dir
/b”显示不带路径的文件名)。
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1
\1.TXT/" >>zipup.bat
使用SED:Sed接受一个或多个编辑命令,并且每读入一行后就依次应用这些命令。当读入第一行输入后,sed对其应用所有的命令,然后将结果输出。接着
再读入第二行输入,对其应用所有的命令……并重复这个过程。上一个例子中sed由标准输入设备(即命令解释器,通常是以管道输入的形式)获得输入。在命令
行给出一个或多个文件名作为参数时,这些文件取代标准输入设备成为sed的输入。sed的输出将被送到标准输出(显示器)。因此:
cat filename | sed
‘10q‘
# 使用管道输入
sed ‘10q‘
filename
# 同样效果,但不使用管道输入
sed ‘10q‘ filename >
newfile
# 将输出转移(重定向)到磁盘上
括号语法:前面的例子对sed命令基本上都使用单引号(‘...‘)而非双引号("...")这是因为sed通常是在Unix平台上使用。单引号 下,Unix的shell(命令解释器)不会对美元符($)和后引号(`...`)进行解释和执行。而在双引号下美元符会被展开为变量或参数的值,后引号 中的命令被执行并以输出的结果代替后引号中的内容。而在“csh”及其衍生的shell中使用感叹号(!)时需要在其前面加上转义用的反斜杠(就像这 样:\!)以保证上面所使用的例子能正常运行(包括使用单引号的情况下)。DOS版本的Sed则一律使用双引号("...")而不是引号来圈起命令。
‘\t‘的用法:为了使本文保持行文简洁,我们在脚本中使用‘\t‘来表示一个制表符。但是现在大部分版本的sed还不能识别‘\t‘的简写方式,因此当 在命令行中为脚本输入制表符时,你应该直接按TAB键来输入制表符而不是输入‘\t‘。下列的工具软件都支持‘\t‘做为一个正则表达式的字元来表示制表 符:awk、perl、HHsed、sedmod以及GNU sed v3.02.80。
不同版本的SED:不同的版本间的sed会有些不同之处,可以想象它们之间在语法上会有差异。具体而言,它们中大部分不支持在编辑命令中间使用标签
(:name)或分支命令(b,t),除非是放在那些的末尾。这篇文档中我们尽量选用了可移植性较高的语法,以使大多数版本的sed的用户都能使用这些脚
本。不过GNU版本的sed允许使用更简洁的语法。想像一下当读者看到一个很长的命令时的心情:
sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d
好消息是GNU sed能让命令更紧凑:
sed
‘/AAA/b;/BBB/b;/CCC/b;d‘
# 甚至可以写成
sed ‘/AAA\|BBB\|CCC/b;d‘
此外,请注意虽然许多版本的sed接受象“/one/ s/RE1/RE2/”这种在‘s‘前带有空格的命令,但这些版本中有些却不接受这样的命令:“/one/! s/RE1/RE2/”。这时只需要把中间的空格去掉就行了。
速度优化:当由于某种原因(比如输入文件较大、处理器或硬盘较慢等)需要提高命令执行速度时,可以考虑在替换命令(“s/.../.../”)前面加上地址表达式来提高速度。举例来说:
sed ‘s/foo/bar/g‘
filename
# 标准替换命令
sed ‘/foo/ s/foo/bar/g‘
filename # 速度更快
sed ‘/foo/ s//bar/g‘
filename
# 简写形式
当只需要显示文件的前面的部分或需要删除后面的内容时,可以在脚本中使用“q”命令(退出命令)。在处理大的文件时,这会节省大量时间。因此:
sed -n ‘45,50p‘
filename
# 显示第45到50行
sed -n ‘51q;45,50p‘
filename
# 一样,但快得多
标签:
原文地址:http://www.cnblogs.com/x113/p/4679131.html