Skip to content

Instantly share code, notes, and snippets.

@jaytaylor
Last active March 4, 2024 23:39
Show Gist options
  • 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
@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