不使用正则表达式替换字符串 [英] Replace string without regex

查看:195
本文介绍了不使用正则表达式替换字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让一个shell脚本在不使用正则表达式(regex)的情况下进行查找和替换,其中包括所有特殊字符,例如!@#$%¨& *()?^〜] } [{{´`>.<,'

I would like to have a shell script to do a find and replace on anything without using regular expressions (regex), that includes all the specials chars such as !@#$%¨&*()?^~]}[{´`>.<,"'

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

So for example the function would be able to receive two parameters where the 1st will be what I want to find, and the second parameter will be what will be replaced with.

示例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可以是任何东西.

The param1 and param2 could be really anything.

我需要使用UNIX 操作系统AIX 它可能是使用sed或awk的KornShell(ksh).我不能使用perl或Java.我也无法在此服务器上安装任何东西.

I need to use UNIX OS AIX it could be KornShell (ksh) using sed or awk. I can not use either perl or Java. I also can not install anything on this server.

推荐答案

我将使用awk以及不使用模式的字符串函数index()和substr()

I'd use awk and the string functions index() and substr() that don't use patterns

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

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

I assume that there may be more than one match per line.

测试

$ 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^]'

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

So you need to pre-process the parameters to escape any backslashes:

$ 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的敏锐度:


To accomodate Ed's astute point:

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

这篇关于不使用正则表达式替换字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆