在linux中,主要通过sed命令来替换文本,通过正则表达式匹配出的命令,可以用sed来灵活的替换掉,极大的节省了工作量。可以说,sed是shell脚本里替换的最主要力量,也是shell脚本里用的最多的命令之一,sed是基于行的编译器,也就是说,它会将匹配到的内容的行打印出来,而且sed有自己的模式空间(内存),也就是说sed并不会改变原文件的内容,但是sed -i 可以直接修改原文件(此功能慎用,很容易造成损失)
sed的用法格式:
sed [option] /PATTERN/COMMAND files
sed [option] ADDR,ADDR/COMMAND files
-n //避免没有被匹配的行显示
-i //直接修改原文件
另外介绍三个基本正则表达式,可以配合sed来匹配单词
\<或\b //锚定词首 [^ ] //取反,除...之外的一个字符
\>或\b //锚定词尾
##一个简单的例子来说明sed的用法:
sed 1,3p /proc/cpuinfo
这条命令将cpuinfo的内容前三行打印两次,如果只要显示前三行,则加 -n 选项,这里的1,3指第一到三行,p是打印的意思。
##扩展几个sed的command:
p 打印 /i 在匹配的内容之前插入
/d 删除 /a 在匹配的内容之后插入
s 替换 /g 全局替换
同时sed也可以使用正则表达式:
例如:
sed "/^model/a\#This is my cpu." /proc/cpuinfo
#看到^了吗?这个命令的意思是在model之后插入#This is my cpu. 注意是model这行后面的一行。
下面介绍替换,替换的模式 s/要查找的内容/要替换成的内容/command
例如:
sed ‘1,$s/yes/YES/' /proc/cpuinfo
#将/proc/cpuinfo里从1到最后一行里的yes替换成YES。
#1,$指从第一行到最后一行 $在这里匹配最后一行,$-2倒数第二行,以此类推。
# 也可以使用/g全局替换,即符合条件的全部替换掉
好了,关于sed的几个练习:
sed练习
1、将/etc/inittab文件中以id开头后面跟了两个冒号且两个冒号间有一个数字的那一行中的那两个冒号间的数字改为3;
2、将/etc/passwd文件中以n开头的所有单词的词首字母改为大写;
3、在/proc/meminfo文件中所有以HugePages开头的行后面添加“# For performancing”一个新行;
4、删除/etc/inittab文件中所有以#开头,或者以一些空白字符后跟一个#开头的行,并且将所有以一个空格后跟一个数字结尾的行中的那个行尾的数字改为0;
答案:1. sed s@^id:[0-9]:@id:3:@g /etc/inittab
#这里的@也是替代符号,当要替换的文本是路径时,这个技巧很好用。
2. sed '1,$s/\bn/N/pg' /etc/passwd
3. sed "/HugePages/a\# For performancing" /proc/meminfo
4. sed -e '/^[[:space:]]*#.*/d' /etc/inittab -e "s/[[:space:]][0-9]$/ 0/g" /etc/inittab
#这里使用了-e 选项,处理两条sed命令 因为文本的开头都有一个空字符,所以^[[:space:]]*#匹配第一个要求,*代表0到任意个
————————————————————————————————————————————————————————————————————————————————
tr命令可以方便的将指定字符替换成别的字符,例如小写字母替换成大写字母,而sed是处理行的,和tr配合使用,可以方便快速的替换行里的字符。
例如:echo abCD | tr ’ab‘ ’AB‘ //将ab替换为AB
tr有一个比较常用的选项 -d, –delete 删除集合1中的字符而不是转换
eco "banana" | tr -d 'a'
#一个sed和tr的脚本
写一个脚本:
1、将/var/目录下所有文件的文件名的首字母和尾字母显示时改为大写;
#!/bin/bash
#: Title:lsvar
#: Synopsis:
#: Date:2011-07-26 23:35:27
#: Version: 1.0
#: Author: Dean
#: Options:
for FILE in `ls /var`; do
FLITER=`echo "$FILE" | sed '1,$s/\([a-zA-Z]\).*/\1/g' | tr 'a-z' 'A-Z'`
LLITER=`echo "$FILE" | sed '1,$s/.*\([a-zA-Z]\)/\1/g' | tr 'a-z' 'A-Z'`
echo "$FILE" | sed "s/[a-zA-Z]\(.*\)[a-zA-Z]/$FLITER\1$LLITER/g"
done