如何在命令行上对百分比编码的字符串进行编码和解码?

如何在命令行上对百分比编码的字符串进行编码和解码?

我如何编码和解码百分比编码命令行上的(URL 编码)字符串?

我正在寻找可以做到这一点的解决方案:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük

答案1

这些命令可以完成您想要的操作(使用 Python 2):

python -c "import urllib, sys; print urllib.quote(sys.argv[1])" æ
python -c "import urllib, sys; print urllib.unquote(sys.argv[1])" %C3%A6

如果要将空格编码为+,请将其替换urllib.quoteurllib.quote_plus

我猜你会想给他们起别名;-)

答案2

尝试以下命令行:

$ echo "%C3%A6ndr%C3%BCk" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
ændrük

您可以将其定义为别名并将其添加到您的 shell 中rc文件:

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

然后,每当你需要它时,只需这样做:

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

狂欢

编写脚本时,可以使用以下语法:

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

但是上述语法无法+正确处理加号(),因此您必须通过将它们替换为空格sed

您还可以使用以下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() 假定数据不包含反斜杠。


bash + xxd

Bash 函数与xxd工具:

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 的要点文件,同样在堆栈溢出


Python

尝试定义以下别名:

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])"'

用法:

$ urlencode "ændrük"
C%26ndrC%3Ck
$ urldecode "%C3%A6ndr%C3%BCk"
ændrük

来源:鲁斯兰斯皮瓦克


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

sed

sed可以通过以下方式使用:

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

awk

尝试不久解决方案:

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

看:使用 awk printf 对文本进行 urldecode


解码文件名

如果您需要从文件名中删除 url 编码,请使用deurlname工具renameutils(例如deurlname *.*)。

也可以看看:


有关的:

答案3

对保留的 URI 字符和非 ASCII 字符进行百分比编码

jq -s -R -r @uri

-s( --slurp) 将输入行读入数组,并且-s -R( --slurp --raw-input) 将输入读入单个字符串。-r( --raw-output) 输出字符串的内容而不是 JSON 字符串文字。

对所有字符进行百分比编码

xxd -p|tr -d \\n|sed 's/../%&/g'

tr -d \\nxxd -p删除每 60 个字符后添加的换行符。

在 Bash 中对除 ASCII 字母数字字符之外的所有字符进行百分比编码

eu () {
    local LC_ALL=C c
    while IFS= read -r -n1 -d '' c
    do 
        if [[ $c = [[:alnum:]] ]]
        then 
            printf %s "$c"
        else
            printf %%%02x "'$c"
        fi
    done
}

如果没有-d ''这个,将会跳过换行符和空字节。如果没有这个,将会用替换IFS=中的字符。如果没有这个,例如,在 UTF-8 语言环境中将会用替换。IFS%00LC_ALL=C%3042

答案4

如同Stefano 回答但在Python 3中:

python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" æ         # to percent-enconding
python3 -c "import urllib.parse, sys; print(urllib.parse.unquote(sys.argv[1]))" %C3%A6  # from percent-enconding

对斜线也进行编码:

python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\"))"

有关差异的更多信息这里

相关内容