문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top