これが純粋なBASHの答えです。
更新: 多くの変更が議論されているため、これをhttps://github.com/sfinktah/bash/blob/master/rawurlencode.inc.shに配置して、誰でも PR を発行できるようにしました。
注: このソリューションは、Unicode またはマルチバイト文字をエンコードすることを意図したものではありません。これは、BASH の控えめなネイティブ機能の範囲外です。'&'、'=' などのように、POST または GET リクエストで引数の受け渡しを台無しにするシンボルをエンコードすることのみを目的としています。
非常に重要な注意: どの言語でも、独自の Unicode 変換関数を記述しようとしないでください。回答の最後を参照してください。
rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}" # You can either set a return variable (FASTER)
REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
}
次の 2 つの方法で使用できます。
easier: echo http://url/q?=$( rawurlencode "$args" )
faster: rawurlencode "$args"; echo http://url/q?${REPLY}
[編集]
ここに対応する rawurldecode() 関数があります。控えめに言っても、これはすばらしいものです。
# Returns a string in which the sequences with percent (%) signs followed by
# two hex digits have been replaced with literal characters.
rawurldecode() {
# This is perhaps a risky gambit, but since all escape characters must be
# encoded, we can replace %NN with \xNN and pass the lot to printf -b, which
# will decode hex for us
printf -v REPLY '%b' "${1//%/\\x}" # You can either set a return variable (FASTER)
echo "${REPLY}" #+or echo the result (EASIER)... or both... :p
}
マッチング セットを使用して、いくつかの簡単なテストを実行できます。
$ diff rawurlencode.inc.sh \
<( rawurldecode "$( rawurlencode "$( cat rawurlencode.inc.sh )" )" ) \
&& echo Matched
Output: Matched
そして、あなたが本当に外部ツールが必要だと感じているなら (まあ、それははるかに速くなり、バイナリファイルなどを実行するかもしれません...) 私は私の OpenWRT ルーターでこれを見つけました...
replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
url_escape.sed は、次のルールを含むファイルでした。
# sed url escaping
s:%:%25:g
s: :%20:g
s:<:%3C:g
s:>:%3E:g
s:#:%23:g
s:{:%7B:g
s:}:%7D:g
s:|:%7C:g
s:\\:%5C:g
s:\^:%5E:g
s:~:%7E:g
s:\[:%5B:g
s:\]:%5D:g
s:`:%60:g
s:;:%3B:g
s:/:%2F:g
s:?:%3F:g
s^:^%3A^g
s:@:%40:g
s:=:%3D:g
s:&:%26:g
s:\$:%24:g
s:\!:%21:g
s:\*:%2A:g
xxd
UTF-8 入力を処理できる BASH (おそらく非常に長いルールセットを使用) でそのようなスクリプトを作成することは不可能ではありませんが、より高速で信頼性の高い方法があります。UTF-8 を UTF-32 にデコードしようとすることは、正確に行うのは簡単なことではありませんが、不正確に行うのは非常に簡単で、機能しない日まで機能すると思い込んでしまいます。
Unicode コンソーシアムでさえ、実際の標準と 100% 互換性がなくなったことを発見した後、サンプル コードを削除しました。
Unicode 標準は常に進化しており、非常に微妙になっています。まとめて実行できる実装は、適切に準拠しているとは言えず、極端な努力によってそれを管理したとしても、準拠したままになります。