Chinaunix

标题: 看看大家遇到这种情况时怎么处理 [打印本页]

作者: wangng_3    时间: 2009-08-23 16:24
标题: 看看大家遇到这种情况时怎么处理
使用shell时间不长,对sed,awk命令和正则表达式还不是很熟,到这里求点经。

使用sed替换字符串时,如果目的串中有一些特殊字符(如:'/'),则需要转义字符‘\’进行转换处理;如果目的串在一个变量里怎么办??

我现在的方法是先把目的串中的特殊字符(如'/')通过 sed 转化成一般字符(如'|'),然后在将可以被sed操作的目的串 替换到文本文件内,然后在用sed 在将一般字符(如'|')替换为特殊字符(如'/'),在写回到文本文件中,完成文本文件的最终替换。好麻烦,感觉好丑,不知道大家在遇到这种情况下如何处理??

比如:

A_file 文件内容:
<property url_address>
         jdbc.db2.rul://1.1.1.1:50001/PM8KV1R1
</proberty>
B_file 文件
<property url_address>
         @{urlclass}
</proberty>

目的:

  需要用A里面的 url value 替换 B 文件里面的  @{urlclass}

实现如下:
#!/bin/bash
chmod +x $0
dsturl=`grep PM8KV1R1 A_file | sed 's/\//|/g'`
sed 's/@{urlclass}/'"$dsturl"'/g' B_file >tmp.xml
sed 's/|/\//g' tmp.xml>tmp1.xml
mv tmp1.xml B_file

结果:
B_file 文件 关于URL的value变为如下:
<property url_address>
          jdbc.db2.rul://1.1.1.1:50001/PM8KV1R1
</proberty>

[ 本帖最后由 wangng_3 于 2009-8-23 17:59 编辑 ]
作者: xiaobaibbb    时间: 2009-08-23 16:41
sed -r 's/(([0-9]{1,3}\.){1,3}){3}[0-9]{1,3}/@{urlclass}/g'
作者: wangng_3    时间: 2009-08-23 18:01
原帖由 xiaobaibbb 于 2009-8-23 16:41 发表
sed -r 's/(([0-9]{1,3}\.){1,3}){3}[0-9]{1,3}/@{urlclass}/g'


怎么理解不了使者的这段代码呢,我是想要把B文件种关于URL的Value修改成A中的.... 能否解释下呢
作者: MYSQLER    时间: 2009-08-23 18:18
awk 'NR==FNR&&/jdbc/{i=$0}NR>FNR{sub(/@{urlclass}/,i,$0);print $0 > "B_file" }' A_file B_file
作者: MYSQLER    时间: 2009-08-23 18:25
如果你两个文件 的内容就是你举例这样的话直接cp不是最好的?
作者: wangng_3    时间: 2009-08-23 19:14
原帖由 MYSQLER 于 2009-8-23 18:25 发表
如果你两个文件 的内容就是你举例这样的话直接cp不是最好的?


B_文件和A_文件的内容都不止这些,两者只是这个有相同的配置项(url_address),这里文件简化了。

另外能不能解释一下,思路是什么,运行不了,对shell了解有限,没看明白思路了,谢谢!
作者: MYSQLER    时间: 2009-08-23 19:42
原帖由 wangng_3 于 2009-8-23 19:14 发表


B_文件和A_文件的内容都不止这些,两者只是这个有相同的配置项(url_address),这里文件简化了。

另外能不能解释一下,思路是什么,运行不了,对shell了解有限,没看明白思路了,谢谢!


把你运行的错误贴上来看看
作者: wangng_3    时间: 2009-08-23 19:54
原帖由 MYSQLER 于 2009-8-23 18:18 发表
awk 'NR==FNR&&/jdbc/{i=$0}NR>FNR{sub(/@{urlclass}/,i,$0);print $0 > "B_file" }' A_file B_file



可以运行,结果正确,谢谢!

能否告诉一下 NR==FNR 和 NR>FNR 的意思?
作者: MYSQLER    时间: 2009-08-23 20:07
NR==FNR  时表示在处理第一个文件
NR>FNR 时表示在处理第二个文件
作者: Shell_HAT    时间: 2009-08-23 20:35
标题: 回复 #8 wangng_3 的帖子
关键是要好好理解一下《十二篇》里的这句话:
FNR支持awk目前操作的记录数。其变量值小于等于NR。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。

http://bbs.chinaunix.net/viewthread.php?tid=448687
作者: wangng_3    时间: 2009-08-23 21:23
标题: 回复 #10 Shell_HAT 的帖子
自己解释下:
当读第一个文件 A_file时,匹配模式/jdbc/ 并将匹配到得记录赋值给 i.
NR==FNR&&/jdbc/{i=$0}

当读到第二个文件时,将$0(因无模式,所以是B_file的全部内容)中的 @{urlclass} 替换成字串“$i”,并将结果写入到 “B_file”,最终大功告成!
NR>FNR{sub(/@{urlclass}/,i,$0);print $0 > "B_file" }'

PS:
问一下与具体例子无关的话题, 拿sed命令说,sed 's/dst_str/$paramter/g' ,如果$parameter的数值内含有特殊字符,正常输入情况下需要使用转义符‘\’ sed命令才认得,这个时候怎么办?有没有什么方法比如说加个双引号等规避这样的问题。
作者: mapleaigh    时间: 2009-08-23 22:57
这种情况的话,换一个定界符就行了吧!用不着将“/”转来转去。
如:把“/”换成“#”之类。
我这么用过。
作者: ncache    时间: 2009-08-24 15:13
sed 's#@{urlclass}#jdbc.db2.rul://1.1.1.1:50001/PM8KV1R1#'




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2