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次)
增删改
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 qian hou
sed null \n
1h 1111 1111
$!G 1111 1111 1111
==>1111 1111
2H 2222 1111 2222
$!G 2222 1111 2222 11112222
==>2222 1111 2222
3H 3333 1111 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"
[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 qian hou
sed null \n
1h 1111 1111
$!G 1111 1111 1111
==>1111 1111
2H 2222 1111 2222
$!G 2222 1111 2222 11112222
==>2222 1111 2222
3H 3333 1111 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"
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24492954/viewspace-1061863/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/24492954/viewspace-1061863/