URL encoder/decoder · Guide
URL Encode Command Line: Encoding in Bash and curl
Bash has no built-in URL encoder, so shell scripts tend to grow hand-written loops that mishandle UTF-8. There are three reliable approaches that avoid writing one.
Let curl do it
If the value is going into a request curl is making, --data-urlencode handles it and needs no external tool:
# POST body
curl -X POST https://example.com/search --data-urlencode "q=salt & pepper"
# GET query string, without sending a body
curl -G https://example.com/search --data-urlencode "q=salt & pepper"The -G form is the one people miss: it moves the encoded data into the query string instead of the body, which is exactly what you want for a GET.
jq for a standalone value
jq handles UTF-8 correctly and is present on most developer machines:
# encode
jq -rn --arg v 'salt & pepper' '$v|@uri' # salt%20%26%20pepper
# decode
jq -rn --arg v 'salt%20%26%20pepper' '$v|@base64d' 2>/dev/null || \
printf '%b' "${v//%/\\x}"For decoding, the printf %b substitution trick works for ASCII and mangles multi-byte UTF-8, which is precisely the failure mode to avoid.
Python for both directions
The most reliable option when correctness matters, since it handles UTF-8 in both directions:
# encode
python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' 'salt & pepper'
# decode
python3 -c 'import sys,urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' 'caf%C3%A9'safe="" is important — without it, quote leaves / unencoded, which is right for paths and wrong for values.
Why not write it in bash
The common loop iterates characters and percent-encodes anything outside [a-zA-Z0-9._~-]. It works for ASCII and corrupts anything else, because bash iterates characters while percent encoding operates on bytes.
Getting UTF-8 right in pure bash requires LC_ALL=C byte iteration and careful quoting. It is achievable and it is never worth it when jq or python3 is one line away.
Frequently asked questions
How do I URL encode in a GET request with curl?
Use curl -G with --data-urlencode; the encoded data goes into the query string.
Why does my bash encoder break on accented characters?
It iterates characters instead of bytes. Percent encoding works on UTF-8 bytes.
Is there a standard urlencode command?
No POSIX one. jq, python3 or curl --data-urlencode are the portable options.
Ready to try it?
Open the free browser-based URL encoder/decoder and apply what you just read — no sign-up, runs locally.
Open the URL encoder/decoder tool