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:

Shell
# 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:

Shell
# 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:

Shell
# 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