Chinaunix
标题:
能否使用sed+正则表达式替换指定行的指定内容
[打印本页]
作者:
lnzfm
时间:
2014-12-04 02:25
标题:
能否使用sed+正则表达式替换指定行的指定内容
某文件夹下有三个文件,内容如下
1.txt
$host = "1.1.1.1";
$host = "1.1.1.1";
$host = "1.1.1.1";
$host = "1.1.1.1";
2.txt
$host = '11.11.11.11';
$host = '11.11.11.11';
$host = '11.11.11.11';
$host = '11.11.11.11';
3.txt
$host = <111.111.111.111>;
$host = <111.111.111.111>;
$host = <111.111.111.111>;
$host = <111.111.111.111>;
整理出需要替换内容的列表保存在replace.me的文件里,格式为
文件名:需替换的行号 该行的内容
1.txt:1 $host = "1.1.1.1";
2.txt:2 $host = '11.11.11.11';
3.txt:3 $host = <111.111.111.111>;
能否使用sed+正则表达式将replace.me的文件里每个文件名里出现的ip地址用正则表达式进行匹配,并将匹配到的地址替换为2.2.2.2,替换后的结果为
1.txt
$host = "2.2.2.2";
$host = "1.1.1.1";
$host = "1.1.1.1";
$host = "1.1.1.1";
2.txt
$host = '11.11.11.11';
$host = '2.2.2.2';
$host = '11.11.11.11';
$host = '11.11.11.11';
3.txt
$host = <111.111.111.111>;
$host = <111.111.111.111>;
$host = <2.2.2.2>;
$host = <111.111.111.111>;
作者:
zooyo
时间:
2014-12-04 08:40
提示:
作者被禁止或删除 内容自动屏蔽
作者:
klainogn
时间:
2014-12-04 09:02
本帖最后由 klainogn 于 2014-12-04 09:12 编辑
$ sed -r 's/^(.*):([0-9]+).*=[^0-9]*([0-9\.]+)[^0-9]+$/sed "1F;\2 s#\3#2.2.2.2#" \1/e;' re.me
1.txt
$host = "2.2.2.2";
$host = "1.1.1.1";
$host = "1.1.1.1";
$host = "1.1.1.1";
2.txt
$host = '11.11.11.11';
$host = '2.2.2.2';
$host = '11.11.11.11';
$host = '11.11.11.11';
3.txt
$host = <111.111.111.111>;
$host = <111.111.111.111>;
$host = <2.2.2.2>;
$host = <111.111.111.111>;
复制代码
如果直接修改原文件,修改为以下内容:
sed -r 's/^(.*):([0-9]+).*=[^0-9]*([0-9\.]+)[^0-9]+$/sed -i "\2 s#\3#2.2.2.2#" \1/e;' re.me
复制代码
作者:
zerostudy
时间:
2014-12-04 09:10
回复
3#
klainogn
厉害!
作者:
Looiml
时间:
2014-12-04 10:11
3楼对sed中s/e命令的运用确实是妙到豪颠啊,相对而言awk看起来就太臃肿了:
awk 'BEGIN{FS="[: <>;\"'"'"'=]+";while(getline <"replace.me"){a[$1]=$2;b[$1]=$4}} a[FILENAME]==FNR{gsub(b[FILENAME],"2.2.2.2")}{print >FILENAME"new"}' files
复制代码
作者:
ly5066113
时间:
2014-12-04 10:24
回复
5#
Looiml
awk -F '[: ]+' '{n=0;while(getline v<$1){if(++n==$2)sub(/\<[0-9.]+\>/,"2.2.2.2",v);print v>$1".new"}}' replace.me
复制代码
作者:
Looiml
时间:
2014-12-04 10:49
回复
6#
ly5066113
类似的方式,不过有误,把\< \>拿掉应该就好了,如果人家要匹配到replace.me里的最后一列才做替换的话可能还得改改,不过跟sed比起来,要做原文件替换的话,又得多加些字符。
作者:
Looiml
时间:
2014-12-04 10:52
回复
6#
ly5066113
不过客观地讲,兄弟的方法可以准确地找文本文件,不必另外花功夫,值得借鉴。
作者:
lnzfm
时间:
2014-12-04 11:03
[ 本帖最后由 lnzfm 于 2014-12-04 11:53 编辑 ]
谢谢各位,我有个地方没看懂,麻烦帮我解释一下。
我感觉替换都是在后面的sed "1F;\2 s#\3#2.2.2.2#" \1/e;这部分完成的,可是为什么
s/^(.*):([0-9]+).*=[^0-9]*([0-9\.]+)[^0-9]+$前面这里使用s/替换模式呢?
我们的口号是更短,更快,更简洁
作者:
blackold
时间:
2014-12-04 12:25
回复
9#
lnzfm
谍中谍,sed中sed。
这相当于两个sed命令。
作者:
klainogn
时间:
2014-12-04 13:09
本帖最后由 klainogn 于 2014-12-04 13:10 编辑
e是把pattern空间里的内容做为shell命令来执行的,所以需要依据当前pattern空间的内容来生成一个合理可执行的shell命令并替换原pattern空间的全部内容
作者:
ckf513728912
时间:
2014-12-04 14:06
写得很妙啊
作者:
zjj2006forever
时间:
2014-12-05 11:49
初学,请教下这个是什么意思啊,尤其是括号里面那段sed -i "\2 s#\3#2.2.2.2#" \1/e;请大牛帮忙解释下
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2