This question already has an answer here:
-
Substitute all characters between two strings by char 'X' using sed
3 answers
I want to change (via bash script using SED command) all the characters in between two given strings with an equal number of X
characters. If say, the first string is %26Name%3d
and the last sting is %26
, then anything in between these two strings I want to replace with an equal number of X
characters. I am reading a file in place. The file is roughly 1MB.
So
SOMETHING%26Name%3dTHISTEXTNEEDSTOBE%26ELSE
to
SOMETHING%26Name%3dXXXXXXXXXXXXXXXXX%26ELSE
OR if start string is %26Last%3d
and ending string is %26
something%26Last%3d%2%2%4%2%4%3%5%%2%2%2%26else
to
something%26Last%3dXXXXXXXXXXXXXXXXXXXXX%26else
I tried below using the sed
command in my bash script but didn't worked perfectly.
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
above declaration and also of myAnd
and myEqual
.
Example:
SOME%26Name%3dTHISTEXTNEEDSTOBE%26Last%3dDUTTA
to
SOME%26Name%3dXXXXXXXXXXXXXXXXX%26Last%3dXXXXX
Here is a sed solution:
sed -e :a -e 's/\(%26Name%3d[X]*\)[^X]\(.*%26\)/\1X\2/;ta'
Hope this is what you are looking for.
As you have mentioned only the startList
is different, I have framed the code to only vary this. Add the rest of the variables to the array in single quotes just like the two I have added.
Script:
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
Detailed Session Output:
$ 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
perl's s///
operator lets you evaluate perl code in the replacement part with the e
flag
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";
}
'
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