缘于一位网友的问题,我做了整理放上来……
————————————————————————————————————————————
一般我喜欢帮助别人解决问题,然后让自己感觉到很有成就感;这种想法是不是有点……哈哈,我就是这样,我比较喜欢看别人的问题,然后尽努力去帮助他。所以,经常有很多的网友来问我一些问题。时间长了,问题也就多了。我觉得应该把这个东西积累下来。所以想以博客的形式放出来,一方面,自己以后忘了可以再来看看;另一方面,希望帮到更多的朋友。
紧紧是个人看法,如果有不同意见的,可以评论留言,勿喷!谢谢~
下面来说一说一位来自群里的网友的提问;
web服务器下面的一个配置文件wp-config.php,在/var/www/目录下的好几个子目录里都有,里面的内容也不尽相同,现在想要修改这些配置文件都有的一行
/**MySQLdatabasepassword*/
define('DB_PASSWORD','GgEv!&C2rsDsdfEWayAz');
把后面单引号里面的内容也就是DB_PASSWORD这个数据库的密码修改为指定的字符串。
是/var/www/目录下所有名称为wp-config.php的文件都要修改
好,碰到这个问题呢,身为菜鸟的我,在老师的教导下,遵循了三个基本原则;
1.首先创建测试文件;
2.其次测试数据处理;
3.真正处理文件;
好,打开准备好的虚拟机;CentOS6.4系统
[root@Jason64-17 ~]# cat /etc/redhat-release CentOS release 6.4 (Final)
查看创建好的测试文件;
[root@Jason64-17 ~]# ls wp-config -l -rw-r--r-- 1 root root 32 Oct 8 14:02 wp-config
创建批量复制脚本;
【我自己写的批量copy脚本,觉得不是很满意,大家如果有好的,可以送上来。嘻嘻~】
[root@Jason64-17 ~]# cat cp.sh #!/bin/bash #program # this program help you copy file to wherever you want #history #09/28/13 lisp first release # read -p "Please input filename i will cp it to everywhere: " filename [ "$filename" == "" ] && echo "you must input filename! " && exit 1 for i in $@ do cp $filename $i done
将其批量复制到多个目录下
[root@Jason64-17 ~]# sh cp.sh /var/www/html/ /var/www/ /var/www/2/ Please input filename i will cp it to everywhere: wp-config.php [root@Jason64-17 ~]# find /var/www/ -type f -name wp-config.php /var/www/html/wp-config.php /var/www/2/wp-config.php /var/www/wp-config.php
测试数据处理
查看要处理的数据;
[root@Jason64-17 ~]# nl wp-config.php 1 <?php 2 /** 3 * The base configurations of the WordPress. 4 * ……omitting…… 21 /** MySQL database password */ 22 define('DB_PASSWORD', 'GgEv!&C2rsDsdfEWayAz'); ……omitting……利用sed进行数据处理测试;
[root@Jason64-17 ~]# sed -n 's/\(PASSWORD....\).*\(..;\)/\1123456\2/gp' wp-config.php define('DB_PASSWORD', '123456');
或者
[root@Jason64-17 ~]# sed -n "s/PASSWORD', '.*'/PASSWORD', '123456'/gp" wp-config.php define('DB_PASSWORD', '123456');在这里要和大家说的就是,使用sed一般我们都是使用hard quote来放在sg的两个肩膀上,但是如果我们要替换的内容里面有单引号(hard quote)呢?
有两种方法(目前我想到的),一种是要么避开它,一种是要么就是直接“面对”它。
第一种就是逃避的方式,我们用\(\)局部替换,将单引号悄悄的括起来了,它也就没什么话可说了。
第二种就是所谓的在外面使用双引号(softquote),那么你里面的单引号就可以畅行无阻了……。
那为什么单引号里面就不能再次使用单引号了呢?
我的理解是,sed语句执行的时候,判断开始的执行条件符号是单引号,那么在执行的过程中再次碰到的单引号它将作为结束来处理(转义根本没用),如果再次碰到单引号,那么它又会以开始来判断,所以你写完语句的时候,在写后面的数据流的源文件的时候试试Tab键,它没反应,就是因为sed还没有结束标识,所以默认现在还不是shell的命令,所以Tab是没用的。只有你写了完整的起始和结束标识符,你Tab的时候才会补全文件名。
【PS:这个也可以作为判断你的sed语句是否写的正确,如果按了半天的Tab,没有补全功能,那说明你的命令是有问题的;awk也是如此哦!】
好了,关键的一步我们搞定了以后,接下来的就小菜一碟啦!
使用find查找出我们要修改的文件
[root@Jason64-17 ~]# find /var/www/ -type f -name wp-config.php /var/www/html/wp-config.php /var/www/2/wp-config.php /var/www/wp-config.php
(这其实就是我刚刚操作的命令,再执行一次,查看有哪些文件)
结合管道利用sed的数据处理功能来对找出来的文件依次修改【测试环节】
[root@Jason64-17 ~]# find /var/www/ -type f -name wp-config.php | xargs sed -n "s/PASSWORD', '.*'/PASSWORD', '123456'/gp" define('DB_PASSWORD', '123456'); define('DB_PASSWORD', '123456'); define('DB_PASSWORD', '123456'); [root@Jason64-17 ~]#
查看测试结果满意了以后,再使用sed-i参数直接对文件进行修改;
[root@Jason64-17 ~]# find /var/www/ -type f -name wp-config.php | xargs sed -i "s/PASSWORD', '.*'/PASSWORD', '123456'/g" [root@Jason64-17 ~]# find /var/www/ -type f -name wp-config.php | xargs grep PASSWORD /var/www/html/wp-config.php:define('DB_PASSWORD', '123456'); /var/www/2/wp-config.php:define('DB_PASSWORD', '123456'); /var/www/wp-config.php:define('DB_PASSWORD', '123456'); [root@Jason64-17 ~]#
这里要注意xargs的用法;有些朋友会问:grep和sed不是支持管道吗?怎么还要加xargs呢?
因为,如果不加xargs,那么sed和grep都是对搜索出来的文件名进行处理了,而不是对文件里面的内容。加了xargs,那么xargs就会将上个命令的结果,作为参数依次传递给下个命令使用。当然有些命令是不支持管道的,因而要加xargs处理一下。
好了,问题此时到这里呢,就基本上已经解决了。
解决这个问题,用到了很多的知识;有find、sed、grep、xargs、还有shell脚本等。收获不小啊~哈哈!
也希望大家多多给建议,这篇文章哪里写的不好的,还忘指正。
对了,对于上述有些命令的用法,有不懂的可以自行查找资料,还可以QQ私聊我哦,有空的话我会及时给你回复的;我的QQ:1031239088。
总之,就是想大家一起进步嘛!