如何使用awk和foreach迭代使用文字方括号

时间:2015-01-28 08:51:54

标签: awk sed foreach csh

我有一个名为mapstring的文件。由于我的模式中的[字符串,我的脚本无效。请帮我找到解决方案。

mapstring的内容

BC1 bc1
BC2 bc2
BAD_BIT[0]  badl0
BAD_BIT[1]  badlleftnr

我正在使用以下脚本来替换文件testfile中的模式

脚本内容

foreach cel (`cat mapstring |awk '{print $1}'`)
    echo $cel
    grep -wq $cel testfile
    if( $status == 0 ) then
        set var2 = `grep -w $cel rajeshmap |awk '{print $2}'`
        sed -i "s% ${cel} % ${var2} %g" testfile
    endif
end

testfile的内容

 rajesh jain BAD_BIT[0] 1234 BAD_BIT[1000]
 jain rajesh DA[0] snps
 raj jain CLK stm

3 个答案:

答案 0 :(得分:1)

这是因为方括号在sed' basic regex syntax中保留。

你必须先使用反斜杠(即\[)来逃避它们(以及其他任何特殊字符),然后再在脚本中使用它们;这本身可以用sed完成,例如:

sed  -re 's/(\[|\])/\\\1/g'

(请注意,在sed(-r)中使用扩展正则表达式可以使这更容易)。

答案 1 :(得分:0)

#!/bin/ksh
# or sh

sed 's/[[\\$^&.+*]/\\&/g' mapstring | while read -r OldCel NewCel
 do
    echo ${OldCel}
    sed -i "/${OldCel}/ {
      s/.*/ & /;s% ${OldCel} % ${NewCel} %g;s/.\\(.*\\)./\\1/
      }" testfile
 done

预先逃脱你的cel值以进行sed操作(你可以添加其他特殊字符,如果出现和依赖于sed的指令,如{(

尝试这样的事情(无法测试,此处没有GNU sed

从@tripleee的好的remarq,这需要是另一个shell,而不是请求中使用的shell,适用于此的脚本

答案 2 :(得分:0)

无论如何,你的脚本效率很低。您可以完全摆脱csh(以及无用的cat和其他风格问题),并使用两个连接的sed脚本执行此操作。

sed 's/[][*\\%]/\\&/g;s/\([^ ]*\) *\(.*\)/s%\1%\2%g/' mapstring |
sed -i -f - testfile

这假设您的sed可以接受标准输入(-f -)上的脚本,并且您的sed方言不了解任何需要转义的其他特殊字符。