缘于一位网友的问题,我做了整理放上来……

————————————————————————————————————————————

一般我喜欢帮助别人解决问题,然后让自己感觉到很有成就感;这种想法是不是有点……哈哈,我就是这样,我比较喜欢看别人的问题,然后尽努力去帮助他。所以,经常有很多的网友来问我一些问题。时间长了,问题也就多了。我觉得应该把这个东西积累下来。所以想以博客的形式放出来,一方面,自己以后忘了可以再来看看;另一方面,希望帮到更多的朋友。

紧紧是个人看法,如果有不同意见的,可以评论留言,勿喷!谢谢~

下面来说一说一位来自群里的网友的提问;

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   
  

利用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

总之,就是想大家一起进步嘛!