#若是知道行号能够用下面的方法
正则表达式
sed
-i
'88 r b.file'
a.
file
#在a.txt的第88行插入文件b.txt
shell
awk
'1;NR==88{system("cat b.file")}'
a.
file
> a.
file
vim
#若是不知道行号,能够用正則匹配
bash
sed
-i
'/regex/ r b.txt'
a.txt
# regex是正则表达式
spa
awk
'/target/{system("cat b.file")}'
a.
file
> c.
file
.net
#sed的話若是不改变源文件,能够去掉-i开关,修改会输出到STDOUT
scala
原文件:code
[root@xiaowu shell]# cat -n file 字符串
1 aaaaget
2 bbbb
3 cccc
4 dddd
如今要在第二行即“bbbb”行的下面添加一行,内容为“xiaowu”
[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file
aaaa
bbbb
xiaowu
cccc
dddd
若是要加两行“xiaowu”能够用一下语句,注意用“\n”换行
[root@xiaowu shell]# sed '/bbbb/a\xiaowu\nxiaowu' file
aaaa
bbbb
xiaowu
xiaowu
cccc
dddd
若是要在第二行即“bbbb”行的上添加一行,内容为“xiaowu”,能够把参数“a”换成“i”
[root@xiaowu shell]# sed '/b/i\xiaowu' file
aaaa
xiaowu
bbbb
cccc
dddd
以上文件中只有一行匹配,若是文件中有两行或者多行匹配,结果有是如何呢?
[root@xiaowu shell]# cat -n file
1 aaaa
2 bbbb
3 cccc
4 bbbb
5 dddd
[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file
aaaa
bbbb
xiaowu
cccc
bbbb
xiaowu
dddd
由结果可知,每一个匹配行的下一行都会被添加“xiaowu”
那么若是指向在第二个“bbbb”的下一行添加内容“xiaowu”,该如何操做呢?
能够考虑先获取第二个“bbbb”行的行号,而后根据行号在此行的下一行添加“xiaowu”
获取第二个“bbbb”行的行号的方法:
方法一:
[root@xiaowu shell]# cat -n file |grep b |awk '{print $1}'|sed -n "2"p
4
方法二:
[root@xiaowu shell]# sed -n '/bbbb/=' file |sed -n "2"p
4
由结果可知第二个“bbbb”行的行号为4,而后再在第四行的前或后添加相应的内容:
[root@xiaowu shell]# sed -e '4a\xiaowu' file
aaaa
bbbb
cccc
bbbb
xiaowu
dddd
[root@xiaowu shell]# sed -e '4a\xiaowu\nxiaowu' file
aaaa
bbbb
cccc
bbbb
xiaowu
xiaowu
dddd
向指定行的末尾添加指定内容,好比在“ccccc”行的行尾介绍“ eeeee”
[root@xiaowu shell]# cat file
aaaaa
bbbbb
ccccc
ddddd
[root@xiaowu shell]# sed 's/cc.*/& eeeee/g' file
aaaaa
bbbbb
ccccc eeeee
ddddd
用Directory替换全部行中的Manager
[root@sishen ~]# sed 's/Manager/Director/' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Director
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Director
只把包含Sales的行中的Manager替换为Director
[root@sishen ~]# sed '/Sales/s/Manager/Director/' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Director
全局标志 g
g表明全局(global)默认状况下,sed会替换每行中第一次出现的original-string,若是你要替换每行中出现的全部original-string,就须要用g
示例 用大写A替换第一次出现的小写字母a
[root@sishen ~]# sed 's/a/A/' employee.txt
101,John Doe,CEO
102,JAson Smith,IT Manager
103,RAj Reddy,Sysadmin
104,AnAnd Ram,Developer
105,JAne Miller,Sales Manager
把全部小写字母a替换为大写字母A
[root@sishen ~]# sed 's/a/A/g' employee.txt
101,John Doe,CEO
102,JAson Smith,IT MAnAger
103,RAj Reddy,SysAdmin
104,AnAnd RAm,Developer
105,JAne Miller,SAles ManAger
注意上述例子会在全部行上进行替换,由于没有指定地址范围
数字标志(1,2,3,·····)
使用数字能够指定original-string出现的次序,只有第n次出现的original-string才会触发替换,每行数字从1开始,最大为512
好比/11会替换每行中第11次出现的original-string
把第二次出现的小写字母a替换为大写字母A
[root@sishen ~]# sed 's/a/A/2' employee.txt
101,John Doe,CEO
102,Jason Smith,IT MAnager
103,Raj Reddy,SysAdmin
104,Anand RAm,Developer
105,Jane Miller,SAles Manager
为了方便如下示例,首先创建以下文件
[root@sishen ~]# vim substitute-locate.txt
locate command is used to locate files
locate command uses datebases to locate files
locate command can also use regex for searching
~
把每行中第二次出的locate替换为find
[root@sishen ~]# sed 's/locate/find/2' substitute-locate.txt
locate command is used to find files
lcaote command uses datebases to locate files
locate command can also use regex for searching
打印标志p(print)
只打印替换后的行
[root@sishen ~]# sed -n 's/John/Johnny/p' employee.txt
101,Johnny Doe,CEO
在以前的数字标志的例子中使用/2来替换第二次出现的locate。第3行中locate只出现了一次因此没有替换任何内容,使用p标志能够只打印替换过的两行
[root@sishen ~]# sed -n 's/locate/find/2p' substitute-locate.txt
locate command is used to find files
locate command uses datebases to find files
[root@sishen ~]#
写标志w
只把替换后的内容写入到out6.txt文件中
[root@sishen ~]# sed -n 's/John/Johnny/w out6.txt' employee.txt
[root@sishen ~]# cat out6.txt
101,Johnny Doe,CEO
把每行中第二次出现的locate替换为find,把替换后的结果保存到文件中,同时显示输入文件全部内容
[root@sishen ~]# sed 's/locate/find/2w out7.txt' substitute-locate.txt
locate command is used to find files
locate command uses datebases to find files
locate command can also use regex for searching
[root@sishen ~]# cat out7.txt
locate command is used to find files
locate command uses datebases to find files
[root@sishen ~]# sed -n 's/locate/find/2w out7.txt' substitute-locate.txt
[root@sishen ~]# cat out7.txt
locate command is used to find files
locate command uses datebases to find files
[root@sishen ~]#
注意加上-n参数就不会输出显示在屏幕上
忽略大小写标志i(ignore)
[root@sishen ~]# sed 's/john/Johnny/' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
加上-i参数后才能够实现替换
[root@sishen ~]# sed 's/john/Johnny/i' employee.txt
101,Johnny Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
执行命令标志w(excuate)
首先创建文件bash-file.txt
[root@sishen ~]# cat bash-file.txt
/etc/passwd
/etc/group
在bash-file.txt文件中的每行前面添加 ls -l 并打印结果
[root@sishen ~]# sed 's/^/ls -l/' bash-file.txt
ls -l/etc/passwd
ls -l/etc/group
在bash-file文件中的每行前面添加ls -l 并把结果做为命令执行
[root@sishen ~]# sed 's/^/ls -l /e' bash-file.txt
-rw-r--r-- 1 root root 1623 Oct 12 10:23 /etc/passwd
-rw-r--r-- 1 root root 818 Oct 12 10:23 /etc/group
使用替换标志组合
使用g,I,p和w的组合
下面的例子将把每行中出现的全部Manager或manager替换为Directory。而后把替换后的内容打印到屏幕上,同时把这些内容保存到out8.txt文件中
[root@sishen ~]# sed -n 's/manager/Director/igpw out8.txt' employee.txt
102,Jason Smith,IT Director
105,Jane Miller,Sales Director
sed替换命令分界符
首先新建一个文件path.txt
reading /usr/local/bin directory
限制使用sed把/usr/local/bin替换为/usr/bin,在下面的例子中,sed默认的分界符/都被\转义
[root@sishen ~]# sed 's/\/usr\/local\/bin/\/usr\/bin/' path.txt
reading /usr/bin directory
这样虽然实现了替换,可是操做中很繁琐,因此你可使用任何一个字符(包括字母,可是不建议这样作)
做为sed替换命令的分界符。如 | 或 ^ 或!如
[root@sishen ~]# sed 'sA/usr/local/bin/A/usr/bin/A' path.txt
reading /usr/local/bin directory
[root@sishen ~]# sed 's|/usr/local/bin|/usr/bin|' path.txt
reading /usr/bin directory
[root@sishen ~]# sed 's@/usr/local/bin@/usr/bin/@' path.txt
reading /usr/bin/ directory
[root@sishen ~]# sed 's^/usr/local/bin^/usr/bin^' path.txt
reading /usr/bin directory
[root@sishen ~]# sed 's!/usr/local/bin!/usr/bin!' path.txt
reading /usr/bin directory
结果都同样,看本身喜爱了
单行内容以上执行多个命令
下面的例子演示了在模式空间内执行两个替换命令的过程
[root@sishen ~]# sed '{
> s/Developer/IT Manager/
> s/Manager/Director/
> }' employee.txt #注意空格
101,John Doe,CEO
102,Jason Smith,IT Director
103,Raj Reddy,Sysadmin
104,Anand Ram,IT Director
105,Jane Miller,Sales Director
分析第4行执行过程
1. 读取数据:在这一步,sed读取内容到模式空间,此时模式空间的内容为:
104,Ananda Ram,Developer
2. 执行命令:第一个命令,s/Developer/IT Manager/执行后,模式空间的内容为:
104,Anand Ram,IT Manager
如今在模式空间上执行第二个命令s/Manager/Director/,执行后,模式空间内容为:
104,Ananda Ram,IT Director
谨记:sed在第一个命令执行的结果上,执行第二个命令
3. 打印内容:打印当前模式空间的内容,以下
104,Ananda Ram,IT Director
4. 重复循环:移动到输入文件的下一行,而后重复执行第一步,即读取数据
&的做用----获取匹配到的模式
挡在replacement-string中使用&时,它会被替换成匹配到的original-string或正则表达式,这是个颇有用的东西
给雇员ID(即第一列的3个数字)加上[ ],如101改为[101]
[root@sishen ~]# sed 's/^[0-9][0-9][0-9]/[&]/g' employee.txt
[101],John Doe,CEO
[102],Jason Smith,IT Manager
[103],Raj Reddy,Sysadmin
[104],Anand Ram,Developer
[105],Jane Miller,Sales Manager
把每一行放进<>中
[root@sishen ~]# sed 's/^.*/<&>/' employee.txt
<101,John Doe,CEO>
<102,Jason Smith,IT Manager>
<103,Raj Reddy,Sysadmin>
<104,Anand Ram,Developer>
<105,Jane Miller,Sales Manager>
分组替换(单个分组)
跟正则表达式中同样,sed中也可使用分组,分组以\(开始,以\)结束,分组能够用在回溯引用中,
回溯引用即从新使用分组所选择的部分正则表达式,在sed替换命令的replacement-string中和正则表达式中,均可以使用回溯引用,
单个分组
[root@sishen ~]# sed 's/\([^,]*\).*/\1/g' employee.txt
101
102
103
104
105
上面例子中:
l 正则表达式\([^,0]*/)匹配字符串从开头到一个逗号之间的全部字符(并将其放入第一个分组中)
l Replacement-string中的\1将代替匹配到的分组
l g 便是全局标志
下面例子只会显示/etc/passwd的第一列,即用户名
[root@sishen ~]# sed 's/\([^:]*\).*/\1/' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
uucp
operator
……
首先创建下面文件,以便使用
[root@sishen ~]# vim number.txt
1
12
123
1234
12345
123456
~
格式化输出,增长可读性
[root@sishen ~]# sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' number.txt
1
12
123
1,234
12,345
123,456
分组替换(多个分组)
可使用多个\和(\)
划分多个分组,使用多个分组时,须要在replacement-string中使用\n来指定第n个分组,以下面的示例如只打印第一列(雇员ID)和第3列(雇员职位)
[root@sishen ~]# sed 's/^\([^,]*\),\([^,]*\),\([^,*]\)/\1,\3/' employee.txt
101,CEO
102,IT Manager
103,Sysadmin
104,Developer
105,Sales Manager
在这个例子中能够看到,original-string中,划分了3个分组,以逗号分隔
l ([^,]*\)第一个分组,匹配雇员ID
l ,为字段分隔符
l ([^,]*\)为第二个分组,匹配雇员姓名
l ,为字段分割符,上面的例子演示了如何使用分组
l \1表明第一个分组,(雇员ID)
l ,出如今第一个分组以后的逗号
l \3表明第二个分组(雇员职位)
注意:sed最多能处理9个分组,分别用\1至\9表示
交换第一列(雇员ID)和第二列(雇员姓名)
[root@sishen ~]# sed 's/^\([^,]*\),\([^,]*\),\([^,]*\)/\2,\1,\3/' employee.txt
John Doe,101,CEO
Jason Smith,102,IT Manager
Raj Reddy,103,Sysadmin
Anand Ram,104,Developer
Jane Miller,105,Sales Manager
sed专有的替换标志
\l 标志(小写的 L,理解为lower)
当在replacement-string中使用\l标志时,它会把紧跟在其后的字符看成小写字符来处理,如你所知,下面的例子将把John换成JOHNNY:
[root@sishen ~]# sed -n 's/John/JOHNNY/p' employee.txt
101,JOHNNY Doe,CEO
下面的例子将把JOHNNY 中的H换成h
[root@sishen ~]# sed -n 's/John/JO\lHNNY/p' employee.txt
101,JOhNNY Doe,CEO
\L 标志
当在replacement-string中使用\L标志时,它会把后面全部的字符都当小写字符来处理,例如:
在replacement-string中的H前放置了\L 标志,它会把H和它后面的全部字符都换成小写:
[root@sishen ~]# sed -n 's/John/JO\LHNNY/p' employee.txt
101,JOhnny Doe,CEO
\u标志(理解为upper)和\l相似,只不过是把字符换成大写,当在replacemen-string中使用\u标志时,它会把紧跟其后的字符看成大写字符来处理,下面的例子中,replacement-string里面的h前面有\u的标志,因此h将被换成大写的H:
[root@sishen ~]# sed -n 's/John/jo\uhnny/p' employee.txt
101,joHnny Doe,CEO
\U标志
当在replacement-string中使用\U标志时,它会把后面全部的字符都看成大写字符来处理。以下:replacement-string里面的h前面有U的标志,因此h及其后的全部字符都将被换成大写:
[root@sishen ~]# sed -n 's/John/jo\Uhnny/p' employee.txt
101,joHNNY Doe,CEO
\E标志(理解为exit)
\E标志须要和\U或者\L一块儿使用,他将关闭\U或\L的功能,例如将字符串“Johnny Boy”的每一个字符都以大写的形式打印出来,由于在replacement-string前面使用了\U标志
[root@sishen ~]# sed -n 's/John/\UJohnny Boy/p' employee.txt
101,JOHNNY BOY Doe,CEO
下面将把John换成JOHNNY Boy
[root@sishen ~]# sed -n 's/John/\UJohnny\E Boy/p' employee.txt
101,JOHNNY Boy Doe,CEO
由于在Johnny后面使用了\E标志,关闭了\U的功能
替换标志的用法
以下将雇员ID都显示为大写,职位都显示为小写:
[root@sishen ~]# sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\U\2\E,\1,\L\3/' employee.txt
JOHN DOE,101,ceo
JASON SMITH,102,it manager
RAJ REDDY,103,sysadmin
ANAND RAM,104,developer
JANE MILLER,105,sales manager
这个例子中
l \U\2\3把第二个分组转换为大写,而后使用\E关闭转换
l \L\3 把第三分组转换为小写
mac环境下的几个使用例子:
一、将a.txt中的public request所有替换成public requestUrl sed -i ".bak" 's/public request/public requestUrl/g' a.txt 二、在a.txt的第66行插入test字符串 sed -i -e '66a \ //注意此处必须换行 test' a.txt 三、在a.txt中包含public scalar的行下,插入test字符串 sed -i "" '/public scale/a \ test' a.txt 四、在a.txt的第16行插入b.txt内容,例如b.txt在/home/b.txt,则$1即为/home,拼完整路径也可 sed -i ".bak" '16 r '$1'/b.txt' a.txt 五、在a.txt中bb/bb行下,插入c.txt内容 sed -i ".bak" '/bb\/bb/ r c.txt' a.txt 六、只替换首次出现符合条件的字符串,如将a.txt中首次出现value:true的替换为value:false sed -i ".bak" '1,/value: true/ s/value: true/value: false/' a.txt 七、将a.txt中,每行第2次出现的a替换为A sed 's/a/A/2' a.txt