String 将一行中两个字符串之间的所有字符替换为';X';

String 将一行中两个字符串之间的所有字符替换为';X';,string,bash,shell,sed,String,Bash,Shell,Sed,我想更改(通过使用SED命令的bash脚本)两个给定字符串之间的所有字符,并使用相同数量的X字符。如果说,第一个字符串是%26Name%3d,最后一个字符串是%26,那么这两个字符串之间的任何内容都要替换为相同数量的X字符。我正在就地读取一个文件。该文件大约为1MB 所以 到 或者如果开始字符串是%26Last%3d,结束字符串是%26 something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else 到 我在下面的bash脚本中尝试使用sed命令,但效果并不

我想更改(通过使用SED命令的bash脚本)两个给定字符串之间的所有字符,并使用相同数量的
X
字符。如果说,第一个字符串是
%26Name%3d
,最后一个字符串是
%26
,那么这两个字符串之间的任何内容都要替换为相同数量的
X
字符。我正在就地读取一个文件。该文件大约为1MB

所以

或者如果开始字符串是
%26Last%3d
,结束字符串是
%26

something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else  

我在下面的bash脚本中尝试使用
sed
命令,但效果并不理想

file=mylog.log
myAnd=\\%26
myEqual=\\%3d
startList=Name\|Last
end_str="\%26"
search_str="$myAnd""(""$startList"")""$myEqual"

sed -i -E ':a; s/('"$search_str"'X*)[^X](.*'"$end_str"')/\1X\2/; ta' "$file"
PS
startList=Name\| Last
以上声明以及
myAnd
myEqual
的声明

例如:

SOME%26Name%3dTHISTEXTNEEDSTOBE%26Last%3dDUTTA  
to  
SOME%26Name%3dXXXXXXXXXXXXXXXXX%26Last%3dXXXXX  

perl的
s///
操作符允许您使用
e
标志评估替换部分中的perl代码

perl -e '
    my @strings = qw{
        SOMETHING%26Name%3dTHISTEXTNEEDSTOBE%26ELSE
        something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else
    };
    my $start = q{%26(?:Name|Last)%3d};
    my $stop = q{%26};
    for my $str (@strings) {
        (my $copy = $str) =~ s/$start\K(.*?)(?=$stop)/"X" x length($1)/ge;
        print "$str\n$copy\n";
    }
'

以下是一个sed解决方案:

sed -e :a -e 's/\(%26Name%3d[X]*\)[^X]\(.*%26\)/\1X\2/;ta'

希望这就是你要找的

正如您所提到的,只有
startList
是不同的,我将代码框定为只改变这一点。用单引号将其余变量添加到数组中,就像我添加的两个一样

脚本:

file=/path/to/your/file
declare -a arr=('%26Name%3d' '%26Last%3d')
for i in "${arr[@]}";
do
sed -i -e :a -e "s/\($i[X]*\)[^X]\(.*%26\)/\1X\2/;ta" $file;
done
详细的会话输出:

$ cat script.sh
file=/home/siju/Desktop/test
declare -a arr=('%26Name%3d' '%26Last%3d')
for i in "${arr[@]}";
do
sed -i -e :a -e "s/\($i[X]*\)[^X]\(.*%26\)/\1X\2/;ta" $file;
done
$ 
$ cat test
SOMETHING%26Name%3dTHISTEXTNEEDSTOBE%26ELSE  
something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else 
$ 
$ ./script.sh 
$ cat test
SOMETHING%26Name%3dXXXXXXXXXXXXXXXXX%26ELSE  
something%26Last%3dXXXXXXXXXXXXXXXXXXXXX%26else 

我希望这不是文化上的不敏感,但是
s/want/want to/g
谢谢glenn,但不幸的是,我只在bash脚本中通过sed命令读取文件,我只需要替换文件中的文本。你们能给我一个bash环境的解决方案吗?我不知道如何在sed中实现它。查看手册:--perl解决方案是有效的“bash环境解决方案”,谢谢。我会试试你建议的解决方案。。。但若你们不介意的话,你们能给我一个使用startList和end_str变量的解决方案吗?原因是我在startList中有大约15-20个项目,我不想对每个项目重复sed命令15-20。提前谢谢。。但是如果数据是这样的话,它就失败了
SOMETHING%26Name%3thistextneedstobe
基本上,行尾不被视为停止点。二,<代码>某些内容%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26Name%3d%%%26基本上,如果出现了一次以上的“开始”元素,则不会执行此操作correctly@PuneetJain当前位置自从我回答这个问题以来,你已经三次实质性地改变了这个问题。(当一个以上的起始元素出现在字符串中时,不可能猜出你认为什么是正确的行为)这不是使用这个网站的正确方法。试着去理解这个解决方案,如果你发现还有一些你不知道怎么做的事情,把它简化成一个简单的例子,作为一个新问题来问。抱歉@Beta。我保证下次我会向集中区域提问。再次抱歉…如果我可以问你,你介意给出这个更新问题的解决方案吗。。这是问题的最后编辑,我保证。谢谢。。但是如果数据是这样的话,它就失败了
SOMETHING%26Name%3thistextneedstobe
基本上,行尾不被视为停止点。二,<代码>某些内容%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26Name%3d%%%26基本上,如果出现一次以上的“开始”元素,则它不能正确执行
SOMETHING%26Name%3dTHISTEXTNEEDSTOBE%26ELSE
SOMETHING%26Name%3dXXXXXXXXXXXXXXXXX%26ELSE
something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else
something%26Last%3dXXXXXXXXXXXXXXXXXXXXX%26else
sed -e :a -e 's/\(%26Name%3d[X]*\)[^X]\(.*%26\)/\1X\2/;ta'
file=/path/to/your/file
declare -a arr=('%26Name%3d' '%26Last%3d')
for i in "${arr[@]}";
do
sed -i -e :a -e "s/\($i[X]*\)[^X]\(.*%26\)/\1X\2/;ta" $file;
done
$ cat script.sh
file=/home/siju/Desktop/test
declare -a arr=('%26Name%3d' '%26Last%3d')
for i in "${arr[@]}";
do
sed -i -e :a -e "s/\($i[X]*\)[^X]\(.*%26\)/\1X\2/;ta" $file;
done
$ 
$ cat test
SOMETHING%26Name%3dTHISTEXTNEEDSTOBE%26ELSE  
something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else 
$ 
$ ./script.sh 
$ cat test
SOMETHING%26Name%3dXXXXXXXXXXXXXXXXX%26ELSE  
something%26Last%3dXXXXXXXXXXXXXXXXXXXXX%26else