替换没有正则表达式的字符串

 流行天王MJ 发布于 2023-02-06 11:17

我希望有一个shell脚本来执行查找和替换,而不使用正则表达式(正则表达式),其中包括所有特殊字符,如!@#$%¨&*()?^〜]} [{' `> <","

因此,例如,函数将能够接收两个参数,其中第一个将是我想要找到的,第二个参数将被替换为.

例1:

File1:
BETWEEN TO_DATE('&1','YYYY-MM-DD') +1  and TO_DATE('&2','YYYY-MM-DD') +15

First parameter: TO_DATE('&1','YYYY-MM-DD') 
Second parameter: TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS') 

File1 after calling the function to replace:

BETWEEN TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS')  +1  and TO_DATE('&2','YYYY-MM-DD') +15

例2:

File2:
This is just a test/2^

Paramter1: test/2^
Paramter1: testing\$2^]'

File2 after calling the function to replace:
This is just a test/2^

param1和param2可以是任何东西.

我需要使用UNIX OS AIX,它可以是使用sed或awk的KornShell(ksh).我不能使用perl或Java.我也无法在这台服务器上安装任何东西.

1 个回答
  • 我使用awk和不使用模式的字符串函数index()和substr()

    awk -v find="$param1" -v repl="$param2" '{
        while (i=index($0,find)) 
            $0 = substr($0,1,i-1) repl substr($0,i+length(find))
        print
    }' file
    

    我假设每行可能有多个匹配.


    测试

    $ param1="TO_DATE('&1','YYYY-MM-DD')"
    $ param2="TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS')"
    $ awk -v find="$param1" -v repl="$param2" '{
        while (i=index($0,find)) 
            $0 = substr($0,1,i-1) repl substr($0,i+length(find))
        print
    }' << END
    BETWEEN TO_DATE('&1','YYYY-MM-DD') +1  and TO_DATE('&2','YYYY-MM-DD') +15
    END
    
    BETWEEN TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS') +1  and TO_DATE('&2','YYYY-MM-DD') +15
    

    第二次测试有点问题:

    $ param1='test/2^'
    $ param2='testing\$2^]'\'
    $ awk -v find="$param1" -v repl="$param2" '{
        while (i=index($0,find)) 
            $0 = substr($0,1,i-1) repl substr($0,i+length(find))
        print
    }' <<< "This is just a test/2^"
    
    awk: warning: escape sequence `\$' treated as plain `$'
    This is just a testing$2^]'
    

    因此,您需要预处理参数以转义任何反斜杠:

    $ awk -v find="$(sed 's/\\/&&/g' <<< "$param1")" \
          -v repl="$(sed 's/\\/&&/g' <<< "$param2")" \
    '{
        while (i=index($0,find)) 
            $0 = substr($0,1,i-1) repl substr($0,i+length(find))
        print
    }' <<< "This is just a test/2^"
    
    This is just a testing\$2^]'
    

    为了适应Ed的精明点:

    param1=foo
    param2=_foo_
    awk -v find="$(sed 's/\\/&&/g' <<< "$param1")" \
        -v repl="$(sed 's/\\/&&/g' <<< "$param2")" \
    '
        index($0, find) {
            start = 1
            line = $0
            newline = ""
            while (i=index(line, find)) {
                newline = newline substr(line, 1, i-1) repl
                start += i + length(find) - 1
                line = substr($0, start)
            }
            $0 = newline line
        }
        {print}
    ' <<END
    abcfoodeffooghifoobar
    food
    blahfoo
    no match
    END
    
    abc_foo_def_foo_ghi_foo_bar
    _foo_d
    blah_foo_
    no match
    

    2023-02-06 11:18 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有