web-dev-qa-db-ja.com

URLエンコーディングのデコード(パーセントエンコーディング)

URLエンコードをデコードしたいのですが、これを行うための組み込みツールはありますか、またはこれを行うsedコードを誰かに提供してもらえますか?

nix.stackexchange.com とインターネットを少し検索しましたが、urlエンコーディングをデコードするためのコマンドラインツールが見つかりませんでした。

私がやりたいことは、単にtxtファイルを編集して次のようにすることです。

  • %21!になります
  • %23#になります
  • %24$になります
  • %26&になります
  • %27'になります
  • %28(になります
  • %29)になります

等々。

106
DisplayName

これらを見つけたPython必要なことを行う1つのライナー:

Python2

$ alias urldecode='python -c "import sys, urllib as ul; \
    print ul.unquote_plus(sys.argv[1])"'

$ alias urlencode='python -c "import sys, urllib as ul; \
    print ul.quote_plus(sys.argv[1])"'

Python3

$ alias urldecode='python3 -c "import sys, urllib.parse as ul; \
    print(ul.unquote_plus(sys.argv[1]))"'

$ alias urlencode='python3 -c "import sys, urllib.parse as ul; \
    print (ul.quote_plus(sys.argv[1]))"'

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B

参考文献

120
slm

sed

次のコマンドラインを試してください:

_$ sed 's@+@ @g;s@%@\\x@g' file | xargs -0 printf "%b"
_

または_echo -e_を使用した次の代替:

_$ sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' file | xargs echo -e
_

注:上記の構文は_+_をスペースに変換せず、すべての改行を含む可能性があります。


これをエイリアスとして定義し、シェルrcファイルに追加できます。

_$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'
_

次に、必要なときはいつでも、次のようにします。

_$ echo "http%3A%2F%2Fwww" | urldecode
http://www
_

Bash

スクリプトを作成するときは、次の構文を使用できます。

_input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")
_

ただし、上記の構文はプラス(_+_)を正しく処理しないため、sedを介して、または @ isaac で提案されているように、これらをスペースで置き換える必要があります。構文:

_decoded=$(input=${input//+/ }; printf "${input//%/\\x}")
_

次のurlencode()およびurldecode()関数も使用できます。

_urlencode() {
    # urlencode <string>
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done
}

urldecode() {
    # urldecode <string>

    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}
_

上記のurldecode()は、データにバックスラッシュが含まれていないことを前提としています。

以下は、Joelの同様のバージョンです。 https://github.com/sixarm/urldecode.sh


bash + xxd

xxdツールを使用したBash関数:

_urlencode() {
  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf "$c" | xxd -p -c1 | while read x;do printf "%%%s" "$x";done
  esac
done
}
_

cdownのGistファイル 、- stackoverflow にもあります。


PHP

PHPを使用すると、次のコマンドを試すことができます。

_$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas
_

あるいは単に:

_php -r 'echo urldecode("oil+and+gas");'
_

複数行の入力には_-R_を使用します。


Perl

Perlでは _URI::Escape_ を使用できます。

_decoded_url=$(Perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")
_

または、ファイルを処理するには:

_Perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file
_

awk

試す anon 解決策:

_awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..
_

注:パラメータ_-n_はGNU awkに固有です。

参照: テキストをurldecodeするためのawk printfの使用

ファイル名のデコード

ファイル名からURLエンコーディングを削除する必要がある場合は、deurlnameからrenameutilsツールを使用します(例:_deurlname *.*_)。

以下も参照してください。


関連:

67
kenorb

Python標準ライブラリにそのための組み込み関数があります。Python 2では、それは urllib.unquote

decoded_url=$(python2 -c 'import sys, urllib; print urllib.unquote(sys.argv[1])' "$encoded_url")

または、ファイルを処理するには:

python2 -c 'import sys, urllib; print urllib.unquote(sys.stdin.read())' <file >file.new &&
mv -f file.new file

Python 3、それは urllib.parse.unquote

decoded_url=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' "$encoded_url")

または、ファイルを処理するには:

python3 -c 'import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))' <file >file.new &&
mv -f file.new file

Perlでは URI::Escape

decoded_url=$(Perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

または、ファイルを処理するには:

Perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

POSIXポータブルツールにこだわりたい場合、厄介なのは、16進数を解析しないawkだけが深刻な候補であるためです。 BusyBoxを含む一般的なawk実装の例については、 awk printfを使用してテキストをurldecodeする を参照してください。

単純なsedコマンドを使用する場合は、以下を使用します。

sed -e 's/%21/!/g' -e 's/%23/#/g' -e 's/%24/$/g' -e 's/%26/\&/g' -e "s/%27/'/g" -e 's/%28/(/g' -e 's/%29/)/g'

しかし、(たとえばsedscript)のようなスクリプトを作成する方が便利です。

s/%21/!/g
s/%23/#/g
s/%24/$/g
s/%26/\&/g
s/%27/'/g
s/%28/(/g
s/%29/)/g

次に、sed -f sedscript < old > newを実行します。これにより、必要に応じて出力されます。


簡単にするために、コマンド urlencode も直接使用できますgridsite-clientsパッケージは(Ubuntu/DebianシステムではSudo apt-get install gridsite-clientsから)インストールできます。

名前

    urlencode-文字列をURLエンコード形式との間で変換する
概要
    urlencode [-m|-d] string [string ...]

説明

    urlencodeRFC 1738に従って文字列をエンコードします。

    つまり、文字A-Za-z0-9._-は変更されずに渡されますが、他のすべての文字は%HHとして表されます。HHは2桁の大文字の16進数ASCII表現です。たとえば、URL http://www.gridpp.ac.uk/http%3A%2F%2Fwww.gridpp.ac.uk%2Fになります

    urlencodeは、コマンドラインで指定されたすべての文字列の各文字を変換します。複数の文字列が指定されている場合、それらは変換前に区切りスペースで連結されます。

オプション
    -m
      完全な変換の代わりに、GridSiteの「マイルドURLエンコーディング」を実行します。ここで、A-Z a-z 0-9です。 =-_ @および/は変更されずに渡されます。これにより、人間が読める文字列がわずかに多くなりますが、アプリケーションは、スラッシュが意味するディレクトリを作成またはシミュレートする準備をする必要があります。
    -d
      RFC 1738に従って、エンコードではなくURLデコードを実行します。%HHおよび%hh文字列は変換され、+がスペースに変換されることを除いて、他の文字は変更されずに渡されます。

URLのデコードの例:

$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f"
http://unix.stackexchange.com/

$ urlencode -d "Example: %21, %22, . . . , %29 etc"
Example: !, ", . . . , ) etc
11
Pandya

Perlワンライナー:

$ Perl -pe 's/\%(\w\w)/chr hex $1/ge'

例:

$ echo '%21%22' |  Perl -pe 's/\%(\w\w)/chr hex $1/ge'
!"
9
Adrian Pronk

GNU Awk

#!/usr/bin/awk -fn
@include "ord"
BEGIN {
   RS = "%.."
}
{
   printf "%s", $0
   if (RT != "") {
      printf "%s", chr("0x" substr(RT, 2)) 
   }
}
7
Steven Penny

このスレッドでの最良の回答 についてコメントすることはできません。

個人的には、URLのエンコードとデコードに次のエイリアスを使用しています。

alias urlencode='python -c "import urllib, sys; print urllib.quote(  sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

alias urldecode='python -c "import urllib, sys; print urllib.unquote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

どちらのコマンドでも、コマンドライン引数として渡される、または標準入力。なぜなら、両方のワンライナーは、コマンドライン引数(空のものも含む)があるかどうかをチェックしてそれらを処理するか、それ以外の場合は標準入力を読み取るためです。


アップデート2017-05-23(スラッシュエンコーディング)

@Bevorのコメントに応じて。

スラッシュもエンコードする必要がある場合は、空の2番目の引数をquote関数に追加するだけで、スラッシュもエンコードされます。

したがって、最後にurlencodealiasinbashは次のようになります。

alias urlencode='python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")"'

$ urlencode "Проба пера/Pen test"
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ echo "Проба пера/Pen test" | urlencode
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ urldecode %D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test
Проба пера/Pen test

$ echo "%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test" | urldecode
Проба пера/Pen test

$ urlencode "Проба пера/Pen test" | urldecode
Проба пера/Pen test

$ echo "Проба пера/Pen test" | urlencode | urldecode
Проба пера/Pen test
7
DIG mbl

そして別のPerlアプローチ:

#!/usr/bin/env Perl
use URI::Encode;
my $uri     = URI::Encode->new( { encode_reserved => 0 } );
while (<>) {

    print $uri->decode($_)
}

URI::Encodeモジュールをインストールする必要があります。私のDebianでは、単純に実行できます

Sudo apt-get install liburi-encode-Perl

次に、上記のスクリプトを次の内容を含むテストファイルで実行しました。

http://foo%21asd%23asd%24%26asd%27asd%28asd%29

結果は(スクリプトをfoo.plとして保存しました):

$ ./foo.pl
http://foo!asd#asd$&asd'asd(asd)
4
terdon

(主にPosix)シェルでの回答:

_$ input='%21%22'
$ printf "`printf "%s\n" "$input" | sed -e 's/+/ /g' -e 's/%\(..\)/\\\\x\1/g'`"
!"
_

説明:

  • _-e 's/+/ /g_は、空間内の各_+_を変換します(url-encodeノルムで説明)
  • -e 's/%\(..\)/\\\\x\1/g' _%XX_の各_\\xXX_を変換します。 _\_の1つが引用ルールによって削除されることに注意してください。
  • 内部のprintfは、sedに入力を渡すためだけにあります。他のメカニズムで置き換えることができます
  • 外側のprintfは_\\xXX_シーケンスを解釈して結果を表示します。

編集:

_%_は常にURLで解釈される必要があるため、この回答を簡略化することが可能です。さらに、backquotesの代わりにxargsを使用する方がきれいだと思います(@joschに感謝)。

_$ input='%21%22+%25'
$ printf "%s\n" "$input" | sed -e 's/+/ /g; s/%/\\x/g' | xargs -0 printf
!" %
_

残念ながら、(@ joschが気づいたように)_\x_エスケープシーケンスはPosixで定義されていないため、これらのソリューションはPosixに準拠していません。

3

Rubyを使用した別の解決策(受け入れられたpython回答が私にとって機能しなかった)

alias urldecode='Ruby -e "require \"cgi\"; puts CGI.unescape(ARGV[0])"'
alias urlencode='Ruby -e "require \"cgi\"; puts CGI.escape(ARGV[0])"'

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
1
Shiyason

正確にそれを行うBASH関数を次に示します。

function urldecode() {
        echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g")
}
1
Adi D

シェルのみ:

$ x='a%20%25%e3%81%82';printf "${x//\%/\\x}"
a %あ

--または%bを追加して、ダッシュで始まる引数がオプションとして扱われないようにします。

Zshでは、${x//%/a}aを末尾に追加しますが、${x//\%/a}%aに置き換えます。

1
Lri

short文字列の簡単な解決策(シェルは遅いwww):

$ str='q+werty%3D%2F%3B'

$ a=${str//+/ };printf "$(echo "${a//%/\\x}")\n"

q werty=/;
0
Isaac

ここに別のスクリプトからの関連ビットがあります(私は恥ずかしくないように私の youtube.comダウンロードスクリプト 別の答えから盗みました)以前に書いたことがあります。 sedとシェルを使用して、機能するurldecodeを作成します。

set \! \" \# \$ \% \& \' \( \) \* \ \+ \, \/ \: \; \= \? \@ \[ \]
for c do set "$@" "'$c" "$c"; shift; done
curl -s "$url" | sed 's/\\u0026/\&/g;'"$(
    printf 's/%%%X/\\%s/g;' "$@"
)"

私はそれが包括的であることを誓うつもりはありません-そして実際、私はそれを疑います-それは十分に確かにYouTubeを扱いました。

0
mikeserv