Sed基本入门[2] Sed Substitute Command
我们一般情况下使用最频繁的sed命令便是替换命令:s
1、基本语法:
sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile
- 地址范围address-range和模式范围pattern-range是可选的,如果没有指定则会在所有的行上执行替换命令
- s - 告诉sed去执行替换命令
- original-string - 需要被搜索的字符串,可以为正则表达式
- replacement-string - sed将会使用这个字符串来替换 original-string
- substitute-flags - 可选的表示替换的细则
再次提醒:sed不会改变原文件内容,只是改变的模式空间中的内容
示例:用Director去替换Manager
$ 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
示例:只把销售部的Manager替换为Director
$ 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:stands for global,默认sed的替换命令只会替换一行中的第一次出现的original-string,但是如果使用了g标志,则会将一行内所有的original-string替换。
示例:将字母a全部替换为大写的A
$ 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
数字标志:使用数字标志n表示只会替换一行中的第n次出现的original-string
示例:替换一行中第二次出现的小写字母a为大写字母A
$ 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
p:print flag,如果替换成功,则打印被改变后的这行文本,常结合 -n 选项使用(想想使用场景:你只希望打印出发生过替换的文本内容,而不是所有的)
示例:
$ sed -n 's/John/Johnny/p' employee.txt 101,Johnny Doe,CEO
w:Write Flag,将发生过替换的文本写入一个文件
示例:
$ sed -n 's/John/Johnny/w output.txt' employee.txt $ cat output.txt 101,Johnny Doe,CEO
i:Ignore Case Flag,忽略大小写
示例:将所有(对应g标志)不区分大小写的字符串john替换为Johnny
$ sed 's/john/Johnny/ig' employee.txt 101,Johnny Doe,CEO 102,Jason Smith,IT Manager 103,Raj Reddy,Sysadmin 104,Anand Ram,Developer 105,Jane Miller,Sales Manager
e:Execute Flag,将替换后的模式空间中的文本当做命令来执行,并将执行结果写回模式空间
示例,可以通过加和不加e标志的进行对比:
$ cat files.txt /etc/passwd /etc/group
$ sed 's/^/ls -l /' files.txt ls -l /etc/passwd ls -l /etc/group
$ sed 's/^/ls -l /e' files.txt -rw-r--r-- 1 root root 1547 Oct 27 08:11 /etc/passwd -rw-r--r-- 1 root root 651 Oct 27 08:11 /etc/group
三、组合使用多个替换标志
可以将多个替换标志组合使用
示例:将所有的(g)Manager或manager替换为Director(i用以忽略大小写),并将替换后的内容打印输出(p)并写到文件output.txt中(w)
$ sed -n 's/Manager/Director/gipw output.txt' employee.txt 102,Jason Smith,IT Director 105,Jane Miller,Sales Director
四、替换分隔符
我们通常使用 / 作为替换的分隔符,所以如果origina-string或replacement-string中如果出现 / 时,我们就需要用 \ 来进行转义:
$ vi path.txt reading /usr/local/bin directory
$ sed 's/\/usr\/local\/bin/\/usr\/bin/' path.txt reading /usr/bin directory
好丑陋啊,是不是?但事实上我们可以使用任何的字符作为分隔符,例如 | ^ @ ! 等军可以作为分隔符,避免对特殊的字符进行转义:
sed 's|/usr/local/bin|/usr/bin|' path.txt sed 's^/usr/local/bin^/usr/bin^' path.txt sed 's@/usr/local/bin@/usr/bin@' path.txt sed 's!/usr/local/bin!/usr/bin!' path.txt
五、&和替换分组
如果在替换文本中使用了&,则表示整个匹配的文本。
示例:将文本开头的三个数字用中括号[和]阔起来
$ 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
将整行文本使用尖括号括起来
$ 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>
替换分组,可以在original-string中使用\(和\)进行分组,然后在replacement-string中通过\n来使用分组的信息
示例:只保留每行中的id信息
$ sed 's/\([^,]*\).*/\1/g' employee.txt 101 102 103 104 105
在这个示例中,\([^,]*\)用来匹配一直到第一个,出现的字符串;\1表示匹配到的真实字符串
示例:将每个单词的首个大写字母用圆括号括起来
$ echo "The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g' (T)he (G)eek (S)tuff
示例:交换编号列与姓名列的位置
$ sed 's/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1,\3/g' employee.txt John Doe,101,CEO Jason Smith,102,IT Manager Raj Reddy,103,Sysadmin Anand Ram,104,Developer Jane Miller,105,Sales Manager