a\ 表示在当前行后添加一行或多行。多行时 除最后一行外,每行末尾需用“\”续行
sed –i‘/super/a\HHHH a.b.c;’ file_name
sed -i 's/HHHH//g' file_name;
super的下一行插入HHHH…等内容,由于插入的内容开头不能是空格,所以先插入HHHH(可以是其他任意字符)和空格,然后再删掉HHHH,这样就可以实现在新的一行开头插入空格;
c\ 表示用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行;
i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行;
d 表示删除行
sed '2,5d' file_name #删除第二到第五行;
替换:
sed 's/要被替换的字符串/新的字符串/g'
如果没有g标记,则只有每行第一个匹配的字符被替换
sed -i's/被替换的内容/要替换成的内容/' file # -i 直接修改并保存
sed -n's/^test/mytest/p' example
(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。
sed 's/^192.168.0.1/&localhost/'example
&符号表示替换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成192.168.0.1localhost。
sed -n 's//(love/)able//1rs/p' example
love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来
sed -n '5,/^test/p' example #打印从第五行开始到第一个包含以test开始的行之间的所有行。
sed -e '1,5d' -e 's/test/check/' example
(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
sed -n '/test/w file' example
-----在example中所有包含test的行都被写入file里
下一个:n命令
sed '/test/{ n; s/aa/bb/; }' example
如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。
cat filename | sed –n ‘/1024/p’ #打印出含有字串”1024”的行
sed /^$/d filename #可以删除文件中的空行。
sed /^[[:space:]]*$/d filename #可以删除内容为多个空格/tab组成的行。
sed支持反向匹配
----------------------------------------------
sed -n '/bsp/!p' file #匹配不包含bsp的行
正则表达式元字符:
元字符 | 功能 | 示例 |
^ | 行首定位符 | /^my/ 匹配所有以my开头的行 |
$ | 行尾定位符 | /my$/ 匹配所有以my结尾的行 |
. | 匹配除换行符以外的单个字符 | /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* | 匹配零个或多个前导字符 | /my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] | 匹配指定字符组内的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
[^] | 匹配不在指定字符组内的任一字符 | /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行 |
保存已匹配的字符 | 1,20s/self/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 | |
& | 保存查找串以便在替换串中引用 | s/my/**&**/ 符号&代表查找串。my将被替换为**my** |
\< | 词首定位符 | /\<my/ 匹配包含以my开头的单词的行 |
\> | 词尾定位符 | /my\>/ 匹配包含以my结尾的单词的行 |
x\{m\} | 连续m个x | /9\{5\}/ 匹配包含连续5个9的行 |
x\{m,\} | 至少m个x | /9\{5,\}/ 匹配包含至少连续5个9的行 |
x\{m,n\} | 至少m个,但不超过n个x | /9\{5,7\}/ 匹配包含连续5到7个9的行 |
-r, --regexp-extended 在脚本中使用扩展正则表达式
sed -r 's/^(.)(.)/\2/g' passwd #删除文件每行的第二个字符
sed -r 's/(.)$//g' #删除文件每行的最后一个字符
sed -r 's/^([a-Z])([^0-9][^a-Z])(a-Z)/\1\2/g' passwd #删除文件每行的第二个单词
-----------------------------------------------------------------------------------------------------------------------------------
模式空间 和 保持空间
-----------------------------------------------------------------------------------------------------
保持和获取:h命令和G命令
h:模式空间 ----> 保持空间(覆盖)
H:模式空间 --->> 保持空间(追加)
x:模式空间 <---> 保持空间(交换)
g:保持空间 ----> 模式空间(覆盖)
G:保持空间 --->> 模式空间(追加)
所谓模式空间:当前按指定模式匹配到的行的内容;比如 sed -n '/test/p' a.log,其中含有test的行就被复制到模式空间
保持空间:可以理解为把按指定模式把匹配到的行暂时缓存的一个空间;
sed -e '/test/H' -e '$G’ example
任何包含test的行都被复制并追加到该文件的末尾($表示文件最后一行)。
互换:x命令
sed -e '/test/h' -e '/check/x' example #把包含test与check的行互换。
>>cat a.log
test1
test2
check1
check2
>> sed -e '/test/h' -e '/check/x' a.log
test1 # 把test1存入保持空间
test2 # 由于是h ,所以test2 存入保持空间,并把上次存入的test1覆盖掉
test2 # 把保持空间的内容(test2)输出,再把check1存到保持空间
check1 # 把保持空间的内容(check1)输出
>> sed -e '/test/H' -e '/check/x' a.log
test1 # 把test1存入保持空间
test2 # 由于是H ,所以test2 追加存入保持空间,此时保持空间包含test1和test2和空行(初始时,保持空间包含一个空行)
#由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出
test1 # 由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出
test2 # 由于当前行含有check,故交换两个空间内容,并把交换前保持空间的内容输出,把check1存入保持空间
check1 # 把保持空间的内容(check1)输出
>>sed '1h;2H;3G' #把第一行和第二行复制到第三行后面
test1
test2
check1
test1
test2
check2
>>sed '1,2H;3G' #把第一行和第二行复制到第三行后面
test1
test2
check1
#会打印一行空行,为了规避空行使用上面的写法,先存入数据到保持空间,覆盖掉初始的空行
test1
test2
check2
sed 反向输出
电话号码作为表达式的输入,要求若号码不是以021为前缀,则必须把整个号码转换为字符串bar
echo 02188888888 | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_021/021/' | sed 's/^_t_.*$/bar/'
这里只是用Linux命令来与管道演示一下,命令执行的结果将输出02188888888(保持号码不变),步骤说明:
1)第一个表达式 sed 's/^/(.*/)$/_t_/1/' 意思是“在号码前面加一个特殊前缀_t_”,号码02188888888被处理后,第一个表达式将输出 _t_02188888888 。
2)第二个表达式 sed 's/^_t_021/021/' 意思是“若输入的字符串前缀为_t_021,则转化该前缀为021”,此处_t_02188888888 又变回了 02188888888。
3)第三个表达式 sed 's/^_t_.*$/bar/' 意思是“若输入的字符串前缀为_t_,则把整个字符串替换成bar”,此处输入为02188888888,所以本表达式不起作用,最终输出还是02188888888。(即允许拨打该号码)
再看看若输入的是一个非021前缀的号码:
echo 05788888888 | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_021/021/' | sed 's/^_t_.*$/bar/'
1)第一个表达式 sed 's/^/(.*/)$/_t_/1/' 处理结果在号码05788888888前加了前缀:_t_05788888888 。
2)第二个表达式 sed 's/^_t_021/021/' 发现字符串_t_05788888888 不是以_t_021为前缀,所以它将不做任何处理,输出的结果还是_t_05788888888 。
3)第三个表达式 sed 's/^_t_.*$/bar/' 发现字符串前缀为_t_,则把整个字符串替换成了bar
上述表达式只适用于“替换前缀不为XX的字符串”,若要匹配的标识在字符串中间怎么办?
比如,如何实现“请替换不含hero的整个字符串为bar”的要求。
echo 'I am hero yeah' | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_/(.*/)hero//1hero/' | sed 's/^_t_.*$/bar/'
将输出 'I am hero yeah' ,而输入其它字符串,如:
echo 'He is not' | sed 's/^/(.*/)$/_t_/1/' | sed 's/^_t_/(.*/)hero//1hero/' | sed 's/^_t_.*$/bar/'
将输出 'bar'。
应用举例
sed -n 's/^.//gp' /etc/passwd
sed -nr 's/(.)(.*)/\2/p' /etc/passwd
2. 删除文件每行的第二个字符。
sed -nr 's/(.)(.)(.*)/\1\3/p' /etc/passwd
3. 删除文件每行的最后一个字符。
sed -nr 's/.$//p' /etc/passwd
sed -nr 's/(.*)(.)/\1/p' /etc/passwd
4. 删除文件每行的倒数第二个字符。
sed -nr 's/(.*)(.)(.)/\1\3/p' /etc/a.log
5. 删除文件每行的第二个单词。
sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\2\3\5/p' /etc/a.log
6. 删除文件每行的倒数第二个单词。
sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4\5\6/p' /a.log
7. 删除文件每行的最后一个单词。
sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4/p' ./a.log
8. 交换每行的第一个字符和第二个字符。
sed -nr 's/(.)(.)(.*)/\2\1\3/p' /etc/passwd
9. 交换每行的第一个单词和第二个单词。
sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' ./a.log
10. 交换每行的第一个单词和最后一个单词。
sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' ./a.log
sed 's/[0-9]*//g' /etc/passwd
12. 删除每行开头的所有空格。
sed -n 's/^\ *//p' ./a.log
sed -nr 's/( *)(.*)/\2/p' ./a.log
13. 用制表符替换文件中出现的所有空格。
sed -n 's/\ /\t/gp' ./a.log
14. 把所有大写字母用括号()括起来。
sed -nr 's/([A-Z])/(&)/gp' ./test
sed -n 's/[A-Z]/(&)/gp' ./test
15. 打印每行3次
sed 'p;p' pass
16. 隔行删除
sed -n '1~2p' ./a.log #删除奇数行
17. 把文件从第22行到第33行 复制到第44行后面
sed '1,21h;22h;23,33H;44G' ./a.log
18. 把文件从第22行到第33行 移动到第44行后面
sed '22{h;d};23,33{H;d};44G' pass
19. 只显示每行的第一个单词
sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)(.*)/\2/p' /etc/passwd
20. 打印每行的第一个单词和第三个单词
sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\2--\4/p' /etc/passwd
21. 将格式为 mm/yy/dd 的日期格式换成 mm;yy;dd
date +%m/%Y/%d |sed -n 's#/#;#gp'