我想解码URL编码,是否有内置工具可以执行此操作,或者有人可以为我提供可以执行此操作的sed代码?

我确实通过unix.stackexchange.com和互联网进行了一些搜索,但是找不到用于解码url编码的任何命令行工具。

我想要的是只需在一个地方编辑一个txt文件,即可:



%21变为!


%23变为#


%24变成$



%26变成&



%27变成'


%28变为(


%29变为)


依此类推。

评论

stackoverflow.com/questions/6250698/…

#1 楼

找到了这些可以满足您需求的Python内衬:

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


参考文献


来自命令行的Ullencode和urldecode


评论


我很晚才知道,但是有什么办法可以通过原位编辑来做到这一点?

–DisplayName
2014年11月4日,11:18

@DisplayName-听起来像是我的新Q。我会问一下,并参考一下。

–slm♦
2014年11月4日在12:18

流式传输:cat your_lovely_file.csv | python -c“将sys,urllib导入为ul; [sys.stdin中l的sys.stdout.write(ul.quote_plus(l))]”

– Kirill_igum
2015年12月2日15:14



请参阅@DIG mbl的答案,与stdin一起使用。

– starbeamrainbowlabs
18/09/3在14:44

#2 楼

sed

尝试以下命令行:

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


或以下使用echo -e的替代方法:

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


注意:上面的语法可能不会将+转换为空格,并且会占用所有换行符。


您可以将其定义为别名并将其添加到Shell 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相似找到一个版本t: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

尝试匿名解决方案:

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


注意:参数-n特定于GNU awk

请参阅:使用awk printf对文本进行url解码。

解码文件名

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

另请参见:


批量下载时,wget可以解码uri文件名吗?
如何从文件名中删除URI编码?相关:




如何在shell中解码URL编码的字符串?在SO

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


评论


awk:由于这利用了库函数chr(​​),因此很有可能仅在GNU awk(gawk)上运行。但是,在这种情况下,几乎没有POSIX awk的等效项,因为-n选项(允许非十进制参数)是GNU awk的特长。

–syntaxerror
2015年6月27日15:07



您涉及printf的解决方案未考虑到URL可能包含转义的百分号,例如%25。您将它们传递给printf而不用另一个百分比符号(如%%)将它们转义为printf。

– josch
16 Sep 13 '19:57

bash版本要求在顶部使用本地LC_ALL = C,否则所有宽字符(即日文,中文等)都不能正确分成字节。

–费诺斯特
18年8月27日在16:31

github.com/SixArm/urlencode.sh

–解毒
19年4月24日在21:24

使用BSD版本的printf(例如macOS)时,printf版本不起作用,但是在使用GNU Coreutils版本时,它可以正常工作。

–马修·巴克特(Matthew Buckett)
19年4月30日在18:07

#3 楼

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便携式工具,这很尴尬,因为唯一的候选对象是awk,它不解析十六进制数。有关常见awk实现(包括BusyBox)的示例,请参见使用awk printf对文本进行url解码。

#4 楼

Perl一种衬板:

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


示例:

$ echo '%21%22' |  perl -pe 's/\%(\w\w)/chr hex /ge'
!"


评论


当您不想安装perl模块时,此答案很有吸引力。

– Sridhar Sarnobat
2015年11月10日19:36

在MacOS上,只有一个对我来说优雅的作品。

– Qix-蒙尼卡(MS)被盗
19 Mar 27 '19 at 13:02

如果您想一次解析所有级别的URL编码,还可以使用perl -pe s / \%([[:xdigit:]] {2})/ chr hex $ 1 / ge而(/ \%[[ :xdigit:]] {2} /);'它将解码所有%25xx嵌套编码

–scruss
20-10-6在18:04

#5 楼

如果要使用简单的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)的脚本更方便: br />
 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)。


NAME
urlencode-将字符串转换为URL编码形式或从URL编码形式转换字符串。


urlencode [-m|-d] string [string ...]
说明

urlencode根据RFC 1738编码字符串。

也就是说,字符A-Z a-z 0-9 . _-是未经修改地传递的,但是所有其他字符都表示为%HH,
其中HH是它们的两个位大写十六进制ASCII码repr esentation。
例如,URL http://www.gridpp.ac.uk/变为http%3A%2F%2Fwww.gridpp.ac.uk%2F

urlencode转换命令行上给定的所有字符串中的每个字符。如果给出了多个字符串,
在转换之前将它们与空格隔开。

选项
-m而不是完全转换,请在GridSite中进行“轻度URL编码”
AZ AZ 0-9。 =-_ @和/未修改地传递。
这会导致更多易读的字符串
,但是应用程序必须准备好创建或模拟任何斜杠所隐含的目录。
-d请执行URL解码而不是编码,根据RFC1738。
%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


评论


有关sed访问的教程

–潘迪亚
2014年10月4日14:27

这是一个不好的解决方案,因为它需要对每个字符进行硬编码。通过您的代码缺少经常使用的%20转义序列,可以说明此问题。

–概述
2014年10月5日13:43

@Overv我刚刚修改了

–潘迪亚
2014年10月5日14:02

另外,您可能需要仔细检查s /%26 /&/ g的功能。 (我修好了它。)

– G-Man说“恢复莫妮卡”
15年7月16日在6:42

#6 楼

我无法在此线程中评论最佳答案,所以这是我的。

我个人使用以下别名进行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的评论。

如果还需要对斜杠进行编码,只需在quote函数中添加一个空的第二个参数,则斜杠也将被编码。

因此,最后bash中的urlencode别名如下所示:

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


评论


不编码斜线。

– Bevor
17年5月15日在11:41

@Bevor:例子?

– DIG mbl
17年5月22日在3:40

在urlencode“Пробапера”中添加斜杠->结果:不对斜杠进行编码。

– Bevor
17年5月22日在9:21

@Bevor:你是对的。感谢您的评论。我还将更改答案以反映您的评论。

– DIG mbl
17年5月23日在13:49

#7 楼

GNU Awk

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


#8 楼

另一种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)
 


#9 楼

在(主要是Posix)shell中的答案:

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


解释:



-e 's/+/ /g变换空间中的每个+ (如url-encode规范中所述)

-e 's/%\(..\)/\\x/g'转换%XX中的每个\xXX。请注意,\之一将通过引用规则删除。
内部printf就在那里将输入传递给sed。我们可以用任何其他机制代替它。
外部printf解释\xXX序列并显示结果。

编辑:

由于应该始终在URL中解释%,因此它可以简化这个答案。另外,我认为使用xargs而不是反引号(由于@josch)更干净。

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


,不幸的是,(如@josch注意到的)这些解决方案都不与Posix兼容,因为Posix中未定义\x转义序列。

评论


欢迎来到U&L。也许您可以解释这个答案及其作用方式。通常,我们希望答案是带有详细信息的长格式,而不仅仅是代码段。

–slm♦
2014年12月5日12:41

我真的很喜欢这个答案,因为它全面,可移植且不需要额外的较重的外部程序(如perl或python)。对我来说效果很好。

–史蒂夫·威尔斯
15年1月15日在17:05

很好的解决方案。甚至更短,更聪明:... | sed's / + / /g;s/%\(..\)/\\\\x\1/g'。实际上-e选项可以在这里省略...

–syntaxerror
15年6月27日在16:09

@josch是的,printf是破折号中的内置函数,它不能识别\ x转义。您可以使用/ usr / bin / printf而不是printf来使其工作。通常,您应该能够使用命令printf,但是它似乎并没有按预期的方式工作。它继续使用内置的。

–JérômePouiller
16/09/14在11:43



@Jezz确实对\ x转义的支持不属于POSIX:pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html在测试期间,我看到了另一个问题。您可能想用[a-zA-Z0-9] [a-zA-Z0-9]替换.. regex,因为否则诸如'%%%'之类的输入将失败。最后,我还添加了s /%/ %% / g,以确保转义printf的百分比。

– josch
16/09/15在6:03



#10 楼

使用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
 


评论


以前是红宝石,这些语句看起来更小。另外,我更改为ARGF.read,因此可以像使用其他许多实用程序一样将其通过管道传输!

–解毒
20-2-13在15:24

#11 楼

这是一个BASH函数,可以做到这一点:

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


评论


像魅力一样工作

– AbdElraouf Sabri
18年6月21日在14:59

如果要将+字符转换为空格并且不生成任何进程,则可以使用以下命令::“ $ {1 // + /}” && echo -e“ $ {_ //%/ \\ x}”

–杰夫·卡什(Jeff Cash)
20年7月25日在11:48

#12 楼

仅限于Shell:

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


添加--%b可以防止以破折号开头的参数

在zsh中,${x//%/a}在末尾添加了a,但${x//\%/a}%替换了a

#13 楼

这是我之前编写的另一个脚本的相关内容(我只是从另一个答案中无耻地从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。

#14 楼

短字符串(shell慢www)的简单解决方案:

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

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

q werty=/;