There is a built-in function for that in the Python standard library. In Python 2, it's urllib.unquote
.
decoded_url=$(python2 -c 'import sys, urllib; print urllib.unquote(sys.argv[1])' "$encoded_url")
Or to process a file:
python2 -c 'import sys, urllib; print urllib.unquote(sys.stdin.read())' <file >file.new &&
mv -f file.new file
In Python 3, it's urllib.parse.unquote
.
decoded_url=$(python2 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' "$encoded_url")
Or to process a file:
python3 -c 'import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))' <file
file.new &&
mv -f file.new file
In Perl you can use URI::Escape
.
decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")
Or to process a file:
perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file
If you want to stick to POSIX portable tools, it's awkward, because the only serious candidate is awk which doesn't parse hexadecimal numbers. see Using awk printf to urldecode text for examples with common awk implementations including BusyBox.