Percent-Encode a String
Vim, 67 bytes/keystrokes
:s/\c[^a-z!'()*0-9._-]/\='%'.printf(&quot;%02x&quot;,char2nr(submatch(0)))/g&lt;cr&gt;

Note that &lt;cr&gt; represents the enter key, e.g. 0x0D which is a single byte.
This is a pretty straightforward solution. Explanation:
:s/                                                                    &quot;Search and replace
   \c                                                                  &quot;Case-insensitive
     [^a-z!'()*0-9._-]/                                                &quot;A negative range. Matches any character not alphabetc, numeric or in &quot;!'()*0-9._-&quot;
                       \=                                              &quot;Evaluate
                         '%'                                           &quot;a percent sign string
                            .                                          &quot;Concatenated with
                             printf(&quot;%02x&quot;,char2nr(submatch(0)))       &quot;The hex value of the character we just matched
                                                                /g     &quot;Make this apply to ever match
                                                                  &lt;cr&gt; &quot;Actually run the command

That printf(&quot;%02x&quot;,char2nr(submatch(0))) garbage is terribly ungolfy.