代码只是为了学习和理解sed命令而为之,并不代表问题的唯一解或最佳解
一、替换
1.神奇变换(y命令的使用)
sed 'y/ori_letter_list/target_letter_list/' filename
cat filename 1234567890 2345678901 3456789012 4567890123
测试
将文件中1换成A
将文件中2换成B
...
将文件中0换成J
sed 'y/1234567890/ABCDEFGHIJ/' filename ABCDEFGHIJ BCDEFGHIJA CDEFGHIJAB DEFGHIJABC
注意变换关系是按两个list的位置对应变换,y是一个全局命令,拒绝使用后缀flag/g
list1:1234567890
list2:ABCDEFGHIJ
下面再作一个与前例相反的变换
sed 'y/0987654321/ABCDEFGHIJ/' filename JIHGFEDCBA IHGFEDCBAJ HGFEDCBAJI GFEDCBAJIH
2.替换每行第一个匹配
sed 's/regexpr/anyword/' filename sed 's/regexpr/anyword/1' filename
举例:
cat filename 1234567890 2345678901 3456789012 4567890123 sed 's/5/五/' filename 1234五67890 2345678901 34五6789012 4567890123
3.替换每行第n(如果有的话)个匹配
sed "s/regexpr/anyword/${n}" filename cat filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444
举例:
sed "s/4/ 四 /8" filename 111111111111111111 222222222222222222 333333333333333333 4444444 四 4444444444
4.替换每行所有匹配
cat filename 1234567890 2345678901 3456789012 4567890123
举例:
sed 's/3/三/g' filename 12三4567890 2三45678901 三456789012 456789012三
二、行号处理
1.为文件加行号
sed = filename|sed 'N;s/\n/:/' cat filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444
举例:
sed = filename|sed 'N;s/\n/:/' filename 1:111111111111111111 2:222222222222222222 3:333333333333333333 4:444444444444444444
2.仅为文件中的正文行加行号
sed /./= a|sed '/./N;s/\n/:/'
举例:
cat filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444 sed /./= a|sed '/./N;s/\n/:/' filename 1:111111111111111111 3:222222222222222222 4:333333333333333333 6:444444444444444444
三.字串翻转
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
举例:
echo 1234567890|sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' 0987654321
四、选择性输出
1.打印文档奇数行(隔行输出)
sed 'n;d' sed 'x;$!N;x' sed -n 'p;n' 1 3 5 7
2.打印偶数行(隔行输出)
sed -n 'n;p' sed '1d;n;d;' 2 4 6 8
3.删除连续重复行(大量使用了pattern space 文件太大时要注意)
sed '$!N; /^\(.*\)\n\1$/!P; D' #使用 $!N 要当心内存溢出
举例:
cat file 111111111111111111 222222222222222222 222222222222222222 333333333333333333 444444444444444444 444444444444444444 444444444444444444 444444444444444444 444444444444444444 sed '$!N; /^\(.*\)\n\1$/!P; D' filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444
4.合并上下行并以空格相分隔
sed '$!N;s/\n/ /'
举例:
cat file 1234567890 0987654321
执行命令后:
1234567890 0987654321
5.将以\符号结尾的行与下行合并并以空格分隔(拼接断行)
sed -e :a -e '/\\$/N; s/\\\n/ /; ta'
举例:
cat filename 1 111111111111111111\ 2 222222222222222222 3 333333333333333333\ 4 444444444444444444 sed -e :a -e '/\\$/N; s/\\\n/ /; ta' filename 1 111111111111111111 2 222222222222222222 3 333333333333333333 4 444444444444444444
6.按关键字拼接行
如果某行以=开始,则合并到上一行并替代=为空格
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
举例:
cat file 111111111111111111 222222222222222222 =333333333333333333 444444444444444444 sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D' filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444
7.输出匹配行的下一行
sed -n '/regexpr/{n;p;}' filename
举例:
cat filename 1 111111111111111111 2 222222222222222222 3 333333333333333333 4 444444444444444444 sed -n '/^3/{n;p;}' filename 4 444444444444444444
8.显示匹配行的行号并输出匹配行的上行、匹配行、下行
sed -n -e '/regexpr/{=;x;1!p;g;$!N;p;D;}' -e h
举例:
cat filename 1 111111111111111111 2 222222222222222222 3 333333333333333333 4 444444444444444444 sed -n -e '/^3/{=;x;1!p;g;$!N;p;D;}' -e h filename 3 #匹配行的行号 2 222222222222222222 #上一行 3 333333333333333333 #匹配行 4 444444444444444444 #下一行
9.删除文档中某标志区域内的关键字匹配行
删除文档中从being开到end结束的块中包含myword的行
sed '/^begin/,/^end/{/myword/d;}' filename
cat filename myword begin myword Number! myword Number! myword Number! myword Number! end myword Number!
测试:
begin
Number!
Number!
Number!
Number!
end
myword
Number!
五、字串解析
1.从字串中解析出两个子串(前2各字符和后9个字符)
echo "WeLoveChinaUnix"|sed -e 'H;s/\(..\).*/\1/;x;s/.*\(.\{9\}\)$/\1/;x;G;s/\n/ /' We ChinaUnix
2.分解日期串
echo 20030922|sed 's/\(....\)\(..\)\(..\)/\1 \2 \3/'|read year month day echo $year $month $day 2003 09 22
label 以及相关的 t 和 b 的用法
先说说b吧:
比如有文件如下:
cat filename a1234567890 1234567890 1234567890a 1234567890 123456a7890
先要求将其中的"5"替换成" 伍十万 ",但当该行包含字母"a"时,"5"就要替换成" 叁佰万 ".
现看如何通过b来实现:
cat filename.sed #!/bin/sed -f /a/b 5t #如果当前行包含字母"a"则转到label"5t"处 s/5/ 五十万 /g #将5替换成" 五十万 " b #未指明跳转位置时,跳到Script的尾部 :5t #设置名称为"5t"的label s/5/ 叁佰万 /g #提换5为" 叁佰万 "
测试:
sed -f filename.sed filename 1234 五十万 67890 a1234 叁佰万 67890 1234 五十万 67890 1234 叁佰万 67890a 1234 五十万 67890 1234 叁佰万 6a7890
当然,这只是为了说明sed中b的用法,不代表此类问题的最佳解决途径。
!G !N是什么意思?
D:删除模式空间第一个回车符前的所有
N:追加下一行到模式空间。
!D:不执行D。
$!D:只有到最后行(文件末尾行)时不执行D。