问题
What I am trying to achieve is pass the Base64 encoded value captured in the sed
regex to the base64
and have it decoded.
But the problem is, even though it seems like the correct value is being passed to the function using backreference, base64
complains that the input is invalid.
Following is my script -
#!/bin/bash
decodeBaseSixtyFour() {
echo "$1 is decoded to `echo $1 | base64 -d`"
}
echo Passing direct value ...
echo SGVsbG8gQmFzZTY0Cg== | sed -r "s/(.+)$/$(decodeBaseSixtyFour SGVsbG8gQmFzZTY0Cg==)/"
echo Passing captured value ...
echo SGVsbG8gQmFzZTY0Cg== | sed -r "s/(.+)$/$(decodeBaseSixtyFour \\1)/"
And when ran it produces the following output -
Passing direct value ... SGVsbG8gQmFzZTY0Cg== is decoded to Hello Base64 Passing captured value ... base64: invalid input SGVsbG8gQmFzZTY0Cg== is decoded to
I think the output explains what I mean.
Is it possible to do what I am trying to do? If not, why?
回答1:
Perl s///
can do what you want, but I don't think what you're asking for is what you need.
$ echo SGVsbG8gQmFzZTY0Cg== | perl -MMIME::Base64 -pe 's/(.+)/decode_base64($1)/e'
Hello Base64
What's actually happening:
echo SGVsbG8gQmFzZTY0Cg== | sed -r "s/(.+)$/$(decodeBaseSixtyFour \\1)/"
- Before sed starts reading input, the shell notices the process substitution in the double quoted string
- the
decodeBaseSixtyFour
function is called with the string"\\1"
- base64 chokes on the input
\1
and emits the error message - the function returns the string
"\1 is decoded to "
- now the sed script is
's/(.+)$/\1 is decoded to /'
which is how you get the last line.
回答2:
As I commented sed cannot do an equivalent of replace_callback
which is esentially what you're trying to do.
Following awk does close to what you're trying to do:
s="My string is SGVsbG8gQmFzZTY0Cg== something"
awk '{for(i=1; i<=NF; i++) if ($i~/==$/) "base64 -D<<<"$i|getline $i}1'<<<"$s"
My string is Hello Base64 something
来源:https://stackoverflow.com/questions/22544044/passing-sed-backreference-to-base64-command