sed
代码? 我确实通过unix.stackexchange.com和互联网进行了一些搜索,但是找不到用于解码url编码的任何命令行工具。
我想要的是只需在一个地方编辑一个
txt
文件,即可:%21
变为!
%23
变为#
%24
变成$
%26
变成&
%27
变成'
%28
变为(
%29
变为)
依此类推。
#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编码从文件名中,使用来自
deurlname
的renameutils
工具(例如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=/;
评论
stackoverflow.com/questions/6250698/…