LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: frankie

如何用sed以最简单的方式实现这样的字符替换?

[复制链接]
发表于 2004-12-7 03:13:47 | 显示全部楼层
最初由 home_king 发表
这个任务的关键在于正则表达式的构建。

GM3_c?
里面的?就是将前面的c匹配0或1次,也就是说,匹配了两种情况,GM3_c或者GM3_。


To home_king
为什么用?
得不到应有的结果
e0300481@shell:~/tmp$ sed 's|GM2_c?|/opt/at_sing/GM2_c|g' file
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DOPRW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DPRW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DNRW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DRW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DOPW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DPW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DNW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MOPRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MPRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MNRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MOPW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MPW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MNW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2YOPRW

而用*
可以得到结果
e0300481@shell:~/tmp$ sed 's|GM2_c*|/opt/at_sing/GM2_c|g' file
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DNRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DOPW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DPW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DNW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MNRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MOPW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MPW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MNW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2YOPRW

理论上来说
对于? Min Require为None  Max Require为One
对于* Min Require为None  Max Require为No limit
?应该满足要求的啊……

ps. 谢谢home_king指点:p
发表于 2004-12-7 09:55:46 | 显示全部楼层
可能是楼主和home_king、cisco的sed版本不同。
rh9中sed要-r参数:

cat data
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DOPRW
/opt/fg/bin/peercmd store 0.0 GM2_SFC2DPRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MOPRW
/opt/fg/bin/peercmd store 0.0 GM2_cSFC2MPRW
/opt/fg/bin/peercmd store 0.0 GM2_P2DPV
/opt/fg/bin/peercmd store 0.0 GM2_P2DV

cat data|sed -n 's/GM2_/\/opt\/at_sing\/GM2_c/p'|sed -n -r 's/GM2_c{1,2}/GM2_c/p'
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2MPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cP2DPV
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cP2DV
 楼主| 发表于 2004-12-7 13:45:25 | 显示全部楼层
谢谢楼上的各位兄弟了,以下是这个程序的脚本,也算是有了个结果吧。
系统是solaris 8 ,是在ksh shell 中。
顺便说一下,我也试过了,用?的话不能达到效果,可能真是版本的问题吧。
#!/usr/bin/ksh
# changes characters in the files
# Supply full filename
# Works only for chinese NON-SYSTEM formats
# Useage: distrev.sh <filename>
# Writen by Frank

function num_arg {
        if [ ! $1 ]
        then
                echo "ERROR: Usage: chgcht.sh <filename>"
                exit 1
        fi
   }
#---------------------------------

num_arg $1

if [ `cat ${1} | egrep -c -i "GM1"` -gt 0 ]
    then
       cp ${1} ${1}.old
       cat ${1} | sed 's:GM1_c*:/_at_dom_GM12/object/GM1_c:g' > ${1}  

elif [ `cat ${1} | egrep -c -i "GM2"` -gt 0 ]
    then
       cp ${1} ${1}.old
       cat ${1} | sed 's:GM2_c*:/_at_dom_GM12/object/GM2_c:g' > ${1}  

elif [ `cat ${1} | egrep -c -i "GM3"` -gt 0 ]
    then
       cp ${1} ${1}.old
       cat ${1} | sed 's:GM3_c*:/_at_dom_GM3/object/GM3_c:g' > ${1}  

elif [ `cat ${1} | egrep -c -i "SM1"` -gt 0 ]
    then
       cp ${1} ${1}.old
       cat ${1} | sed 's:SM1_c*:/_at_dom_SM1/object/SM1_c:g' > ${1}  

elif [ `cat ${1} | egrep -c -i "SM2"` -gt 0 ]
    then
       cp ${1} ${1}.old
       cat ${1} | sed 's:SM2_c*:/_at_dom_SM2/object/SM1_c:g' > ${1}  

else echo "What are you doing ? Please , don't play with me."
fi
我也还是新手,有什么不对之处大家多多指正
 楼主| 发表于 2004-12-7 14:42:30 | 显示全部楼层
但是有一点我不明白,为什么GM1_c* 不但能匹配GM1_cSFC2MOPRW
,而且也能匹配GM1_SFC2DOPRW,虽然不相信,但是程序执行出来的确是这样,然我觉得相当的奇怪啊。
发表于 2004-12-7 16:06:13 | 显示全部楼层
教主说话风趣:p :p
发表于 2004-12-7 17:05:58 | 显示全部楼层
最初由 frankie 发表
但是有一点我不明白,为什么GM1_c* 不但能匹配GM1_cSFC2MOPRW
,而且也能匹配GM1_SFC2DOPRW,虽然不相信,但是程序执行出来的确是这样,然我觉得相当的奇怪啊。


The
metacharacter ? (question mark) means optional. It is placed after the character
that is allowed to appear at that point in the expression, but whose existence isn't
actually required to still be considered a successful match.

也就是说GM1_c?匹配GM1_和GM1_c

* means "any
number, including none, of the item.

也就是说GM1_c*匹配GM1_和GM1_c和GM1_cc和GM1_ccc等等
发表于 2004-12-7 17:46:19 | 显示全部楼层
最初由 bobbycn 发表
可能是楼主和home_king、cisco的sed版本不同。
rh9中sed要-r参数:


谢谢bobbycn指点

果然用 sed -n -r 's/GM2_c?/\/opt\/at_sing\/GM2_c/p' file
就好了

btw:
  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -r, --regexp-extended
                 use extended regular expressions in the script.

为什么如果不用-n
结果成这样了呢:
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DOPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DPRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DNRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DNRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DRW
/opt/fg/bin/peercmd store 0.0 /opt/at_sing/GM2_cSFC2DRW
每项都重复了一遍:ask
 楼主| 发表于 2004-12-8 09:17:21 | 显示全部楼层
多谢cisco 兄,原来如此。
但是我对我自己的程序都还有点不明白
if 语句中的-gt 0 的具体作用是什么,我试过命令
cat &{1} | egrep -c -i "GM1" ,得到的是文件中出现了多少个GM1字符。我知道if语句用来实现查找到文件中的GM1字符的条件,但是我不清楚他是怎么实现的。
发表于 2004-12-8 18:10:57 | 显示全部楼层
sed -n -e 's=\(gm2_c\)=/opt/at/\1=gp;s=\(gm2_\)\([^c]\)=/opt/at/\1c\2=gp' simple
发表于 2004-12-8 23:21:11 | 显示全部楼层
cat ${1} | egrep -c -i "GM1"
$1指的是程序运行时所带的第一个参数,例如:源程序叫做program,要查找的那个文本文件叫datafile,运行程序./program datafile,datafile就作为了源程序里的$1($2等依次类推,$0为源程序名)。
那么 cat $1 就是print out the content of datafile to the standard output, which is screen,egrep -c -i "GM1" 的作用就是逐行计算文件里GM1的个数
-c, --count
              Suppress normal output; instead print a count of matching  lines
              for  each  input  file.  With the -v, --invert-match option (see
              below), count non-matching lines.
-i, --ignore-case         ignore case distinctions

cat ${1} | egrep -c -i "GM1" 得到的结果就是datafile里GM1的个数

if [ `cat ${1} | egrep -c -i "GM1"` -gt 0 ]
-gt 0 是指值是否大于0
`cat ${1} | egrep -c -i "GM1"` -gt 0 作用就是判断datafile里是否含有GM1,有则进行
cat ${1} | sed 's:GM1_c*:/_at_dom_GM12/object/GM1_c:g' > ${1}
把所有GM1_c?替换成/_at_dom_GM12/object/GM1_c

第一次写这么多,不知道讲清楚没有,有什么疏漏或不对之处还望包含
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表