Skip to content

Instantly share code, notes, and snippets.

@jaytaylor
Last active March 4, 2024 23:39
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaytaylor/5a90c49e0976aadfe0726a847ce58736 to your computer and use it in GitHub Desktop.
Save jaytaylor/5a90c49e0976aadfe0726a847ce58736 to your computer and use it in GitHub Desktop.
URL Encoding in pure bash / sed.
#!/usr/bin/env bash
#
# Credit to @jkishner for https://gist.github.com/jkishner/2fccb24640a27c2d7ac9
#
# Also interesting: https://gist.github.com/cdown/1163649
#
function url_encode() {
echo "$@" \
| sed \
-e 's/%/%25/g' \
-e 's/ /%20/g' \
-e 's/!/%21/g' \
-e 's/"/%22/g' \
-e "s/'/%27/g" \
-e 's/#/%23/g' \
-e 's/(/%28/g' \
-e 's/)/%29/g' \
-e 's/+/%2b/g' \
-e 's/,/%2c/g' \
-e 's/-/%2d/g' \
-e 's/:/%3a/g' \
-e 's/;/%3b/g' \
-e 's/?/%3f/g' \
-e 's/@/%40/g' \
-e 's/\$/%24/g' \
-e 's/\&/%26/g' \
-e 's/\*/%2a/g' \
-e 's/\./%2e/g' \
-e 's/\//%2f/g' \
-e 's/\[/%5b/g' \
-e 's/\\/%5c/g' \
-e 's/\]/%5d/g' \
-e 's/\^/%5e/g' \
-e 's/_/%5f/g' \
-e 's/`/%60/g' \
-e 's/{/%7b/g' \
-e 's/|/%7c/g' \
-e 's/}/%7d/g' \
-e 's/~/%7e/g'
}
# Only invoke url_encode if the script is being executed
# (rather than sourced).
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
url_encode $@
fi
@rojenzaman
Copy link

Thanks! I was searching this, beacuese all solutions includes "/" character. And I just removed "/" line.. That saved my time.

@PenelopeFudd
Copy link

PenelopeFudd commented Jan 26, 2022

I just figured out a way to use curl to do the encoding:

input="Some string/to+url?encode@"
output=$(curl -s -w '%{url_effective}\n' -G / --data-urlencode "=$input" | cut -c 3-)
echo "$output"

Some+string%2Fto%2Burl%3Fencode%40

Of course, if you were encoding the data in order to use it with curl, then you can use --data-urlencode and skip this step. :-)

Tested on curl 7.68.0 and 7.79.1.

An earlier version of this comment used url instead of url_effective and that failed on 7.68.0 but worked on 7.79.1. Sorry if that affected you!

@wzulfikar
Copy link

Nice trick to encode url with curl. Thanks @PenelopeFudd!

@limedaniel
Copy link

Running inside of an Alpine container I ran into problems with the curl method and the sed method seemed incomplete to me, so since we were running a Python project, I ended up with this:

$ python3 -c "from urllib.parse import quote; print(quote('${MY_SPECIAL_STRING}'))"

This'll barf if you have a ' in that string, but outside of that, it should work.

@PenelopeFudd
Copy link

Maybe pipe it in via stdin?

@bellpr
Copy link

bellpr commented Apr 23, 2023

Running inside of an Alpine container I ran into problems with the curl method and the sed method seemed incomplete to me, so since we were running a Python project, I ended up with this:

$ python3 -c "from urllib.parse import quote; print(quote('${MY_SPECIAL_STRING}'))"

This'll barf if you have a ' in that string, but outside of that, it should work.

You could pass in the value as a command-line argument to skip the quoting gymnastics:

$ MY_SPECIAL_STRING="\$foo'bar?" ; echo "${MY_SPECIAL_STRING}" ;  python3 -c 'import sys, urllib.parse ; print(urllib.parse.quote(sys.argv[1]))' "${MY_SPECIAL_STRING}"
$foo'bar?
%24foo%27bar%3F

@marfillaster
Copy link

if you have jq

echo "a b" | jq "@uri" -jRr

@PenelopeFudd
Copy link

Oh, yes, jq is even better than curl at this, mainly because it's shorter, only uses one -, and the curl trick requires a fairly recent version.

Plus, it has a jRr token, which makes me think of hobbits! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment