这是到目前为止我的基本脚本:
#!/bin/bash
host=${1:?'bad host'}
value=
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
#1 楼
使用curl --data-urlencode
;来自man curl
:此发布数据,类似于其他
--data
选项,不同之处在于它执行URL编码。为了符合CGI,<data>
部件应以名称开头,后跟分隔符和内容规范。示例用法:
curl \
--data-urlencode "paramName=value" \
--data-urlencode "secondParam=value" \
http://example.com
有关更多信息,请参见手册页。
这需要curl 7.18.0或更高版本(2008年1月发布)。使用
curl -V
检查您使用的版本。您还可以对查询字符串进行编码:
curl -G \
--data-urlencode "p1=value 1" \
--data-urlencode "p2=value 2" \
http://example.com
# http://example.com?p1=value%201&p2=value%202
评论
似乎仅适用于HTTP POST。此处的文档:curl.haxx.se/docs/manpage.html#--data-urlencode
–斯坦·詹姆斯(Stan James)
2012年4月13日下午6:47
@StanJames如果像这样使用它,curl也可以对GET请求进行编码。 curl -G --data-urlencode“ blah = df ssdf sdf” –data-urlencode“ blah2 = dfsdf sdfsd” http://whatever.com/whatever
–kberg
2012年5月7日20:52
@kberg实际上,这仅适用于查询数据。 curl会附加一个“?”其次是urlencoded参数。如果您要对某些网址后缀进行urlencode(例如某些文档ID的CouchDB GET),则'--data-urlencode'将不起作用。
–散景
2012年8月28日在22:41
不适合curl --data-urlencode“ description =![image]($ url)” www.example.com。知道为什么吗? `
–Khurshid Alam
16 Jun 3'20:37
@NadavB转义“‽
– BlackJack
18年4月19日在9:33
#2 楼
这是纯BASH答案。rawurlencode() {
local string=""
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
}
您可以通过两种方式使用它:
easier: echo http://url/q?=$( rawurlencode "$args" )
faster: rawurlencode "$args"; echo http://url/q?${REPLY}
[编辑]
这是匹配的rawurldecode()函数,该函数-非常谦虚-很棒。现在可以执行一些简单测试:文件等)。我在OpenWRT路由器上发现了此问题。
# 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
}
评论
不幸的是,该脚本在某些字符上失败,例如“é”和“ 1/2”,分别输出“ e%FFFFFFFFFFFFFFFFCC”和“%FFFFFFFFFFFFFFC2”(我相信每个字符循环的b / c)。
–数学
2014年3月24日17:13
它在Bash 4.3.11(1)中对我不起作用。字符串Jogging«àl'Hèze»生成Jogging%20%abà%20l%27Hèze%bb,无法将其馈送到JS解码URIComponent :(
– dmcontador
2015年11月19日在12:07
在第一段代码中,printf的最后一个参数是什么意思?也就是说,为什么要使用双引号,单引号,美元符号,字母c和双引号?单引号可以吗?
– Colin Fraizer
16年5月19日在14:31
@dmcontador-这只是一个不起眼的bash脚本,没有多字节字符或unicode的概念。当它看到像ń(\ u0144)这样的字符时,它将天真地输出%144 ,,(\ u2561)将输出为%2561。正确的原始ururlencoded答案分别是%C5%84%0A和%E2%95%A1。
–嗜尿菌
16年6月8日在9:49
@ Matthematics,@ dmcontador,@ Orwellophile:我之前的评论是错误的。使用xxd的解决方案更有效,并且在任何情况下(对于任何字符)都可以使用。我已经更新了我的脚本。无论如何,看来rawurldecode()函数的表现异常出色。 :)
–tukusejssirs
19-10-13在21:42
#3 楼
另一个选择是使用jq
: $ printf %s 'encode this'|jq -sRr @uri
encode%20this
$ jq -rn --arg x 'encode this' '$x|@uri'
encode%20this
-r
(--raw-output
)输出字符串的原始内容,而不是JSON字符串文字。 -n
(--null-input
)不能从STDIN读取输入。如果您的输入仅包含一行,或者您不想将换行符替换为-R
,则可以用--raw-input
替换-sR
: 或将此百分比编码为所有字节:
--slurp --raw-input
评论
<3它...应该是顶级且被接受的IMO(是的,如果您可以告诉curl进行编码,并且bash具有可以接受的内置函数-但jq似乎是合适的选择,但我距离获得舒适感还很远这个工具的水平)
– nhed
17年11月16日16:16
对于任何想和我一样的人:@uri不是变量,而是用于格式化字符串和转义的文字jq过滤器;有关详细信息,请参见jq手册(对不起,没有直接链接,需要在页面上搜索@uri ...)
–ssc
18年7月13日在11:48
xxd版本只是我一直在寻找的那种东西。即使有点脏,它也很短而且没有依赖性
–瑞安·桑德森(Rian Sanderson)
18年11月21日在15:08
jq到url编码的示例用法:printf“ http:// localhost:8082 /” | jq -sRr'@uri'
–阿舒托什·金达尔(Ashutosh Jindal)
19年8月7日在21:57
我认为这不是最佳答案的唯一原因是因为OP专门询问了curl。如果curl可以单独完成,您就不会循环使用第二个工具jq。但是,这是一个很棒的通用实用程序,可通过脚本或命令行将输出通过管道传输到。
–詹姆森
12月9日19:16
#4 楼
在bash脚本的第二行中使用Perl的URI::Escape
模块和uri_escape
函数:谢谢!评论
URI :: Escape可能未安装,请检查我的答案。
–蓝色
09年11月10日19:50
我修复了此问题(使用echo,pipe和<>),现在即使$ 2包含撇号或双引号,它也可以工作。谢谢!
–dubek
2010年1月3日,9:35
您也可以取消echo:value =“ $(perl -MURI :: Escape -e'print uri_escape($ ARGV [0]);'” $ 2“)”
–克里斯·约翰森(Chris Johnsen)
2010年1月3日,10:31
克里斯·约翰森的版本更好。我在测试表达式中有$ {True},并通过回显使用了它,使uri_escape / Perl变量扩展跳了起来。
–mm2001
2010年1月7日在16:35
@ jrw32982是的,回头看一下,用另一种语言可以完成此任务是好的。如果可以的话,我会收回我的选票,但可惜它目前已锁定。
–thecoshman
14年8月26日在18:36
#5 楼
为了完整起见,许多使用sed
或awk
的解决方案仅翻译一组特殊字符,因此在代码大小上相当大,并且不翻译其他应编码的特殊字符。一种安全的方法urlencode只是对每个单个字节进行编码-即使是允许的字节也是如此。不是字符。
编辑:
xxd在Debian中带有vim-common软件包,而我只是在未安装它的系统上,所以我不想安装它。替代方法是使用Debian中bsdmainutils软件包中的
hexdump
。根据下图,bsdmainutils和vim-common的安装可能性大致相同:http://qa.debian.org/popcon-png.php?packages=vim-common %2Cbsdmainutils&show_installed = 1&want_legend = 1&want_ticks = 1
,但是此处使用
hexdump
而不是xxd
的版本并允许避免使用tr
调用:echo -ne 'some random\nbytes' | xxd -plain | tr -d '\n' | sed 's/\(..\)/%/g'
评论
xxd -plain应该在tr -d'\ n'之后发生!
– qdii
2012年7月8日在16:24
@qdii为什么?这不仅使无法对换行符进行urlencode,而且还会错误地将xxd创建的换行符插入输出。
– josch
2012年7月14日在16:26
@josch。这是完全错误的。首先,任何\ n字符都将由xxd -plain转换为0a。不要相信我,请自己尝试:echo -n -e'\ n'| xxd -plain这证明您的tr -d'\ n'在这里是无用的,因为在xxd -plain之后不能有任何\ n其次,echo foobar在字符串末尾添加了自己的\ n字符,因此xxd -plain没有按照预期的方式使用foobar,而是使用foobar \ n。然后xxd -plain将其转换为以0a结尾的某些字符串,使其不适合用户。您可以添加-n回显来解决它。
– qdii
2012年7月14日在22:49
@qdii实际上-n缺少回显,但是xxd调用属于tr -d调用的前面。它属于此处,因此foobar中的任何换行符都由xxd翻译。 xxd调用后的tr -d是删除xxd产生的换行符。似乎您永远没有足够长的foobar来使xxd产生换行符,但是对于长输入而言,它将如此。因此,tr -d是必需的。与您的假设相反,tr -d不是从输入中删除换行符,而是从xxd输出中删除换行符。我想在输入中保留换行符。您唯一有效的一点是,该回显会添加不必要的换行符。
– josch
2012年7月20日在9:44
@qdii且没有冒犯-我只是认为您是错的,但回声-n确实不见了
– josch
2012年7月20日9:53
#6 楼
变体之一可能很丑陋,但很简单: urlencode() {
local data
if [[ $# != 1 ]]; then
echo "Usage: date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
# If you experience the trailing %0A, use
date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | sed -E 's/..(.*)...//'
string-to-urlencode"
return 1
fi
data="$(curl -s -o /dev/null -w %{url_effective} --get --data-urlencode "" "")"
if [[ $? != 3 ]]; then
echo "Unexpected error" 1>&2
return 2
fi
echo "${data##/?}"
return 0
}
例如,这是单线版本(如Bruno所建议的):
评论
我认为这是重用cURL的URL编码的非常聪明的方法。
–solidsnack
2012年10月24日15:17
这绝对是太棒了!我真希望您将其保留为一行,以便人们可以看到它的真实程度。若要对日期命令的结果进行URL编码…date | curl -Gso / dev / null -w%{url_effective} --data-urlencode @-“” | cut -c 3-(您必须删掉前2个字符,因为curl的输出在技术上是带有查询字符串的相对URL。)
–布鲁诺·布鲁诺斯基(Bruno Bronosky)
13-3-2在3:07
@BrunoBronosky您的单线变体很好,但似乎在编码末尾添加了“%0A”。用户要当心。函数版本似乎没有此问题。
–浏览器
16年8月10日在17:25
为避免最后出现%0A,请使用printf而不是echo。
– Kenorb
18年5月2日,0:11
一个班轮很棒
–斯蒂芬·布鲁姆(Stephen Blum)
18年8月30日在23:31
#7 楼
我发现它在python中更具可读性:encoded_value=$(python -c "import urllib; print urllib.quote('''$value''')")
Triple'确保值中的单引号不会受到伤害。 urllib在标准库中。它适用于这种疯狂的(现实世界)网址:
"http://www.rai.it/dl/audio/" "1264165523944Ho servito il re d'Inghilterra - Puntata 7
评论
我在使用引号和特殊字符使用三引号时遇到了一些麻烦,这似乎基本上适用于所有内容:encode_value =“ $(echo -n” $ {data}“ | python -c” import urllib; import sys; sys.stdout。 write(urllib.quote(sys.stdin.read()))“)”;
–停止莫妮卡·赛利奥(Monica Cellio)
2011年11月14日14:33
Python 3版本将为encode_value = $(python3 -c“ import urllib.parse; print(urllib.parse.quote('''$ value'''))”))。
–Creshal
13年10月10日,11:33
python -c'导入urllib,sys; sys.stdout.writelines(sys.stdin中l的urllib.quote_plus(l,safe =“ / \ n”))'几乎没有引用问题,并且应该具有内存/速度效率(未选中,另存为斜眼) )
–阿洛瓦·马哈德(Alois Mahdal)
2015年11月7日在5:19
引用sys.argv而不是将$ value替换为稍后解析为代码的字符串会更加安全。如果值包含'''+ __import __(“ os”)。system(“ rm -rf〜”)+'''怎么办?
–查尔斯·达菲(Charles Duffy)
16年5月18日在20:45
python -c“ import urllib; print urllib.quote(raw_input())” <<<“ $ data”
– Rockallite
17年2月9日在8:02
#8 楼
我发现以下片段有助于将其粘贴到程序调用链中,其中可能未安装URI :: Escape:perl -p -e 's/([^A-Za-z0-9])/sprintf("%%%02X", ord())/seg'
(源)
评论
为我工作。我将其更改为perl -lpe ...(字母ell)。这删除了结尾的换行符,这是我需要的。
–JohnnyLambada
2012年10月17日18:52
仅供参考,要执行相反的操作,请使用perl -pe's / \%(\ w \ w)/ chr hex $ 1 / ge'(来源:unix.stackexchange.com/questions/159253/…)
– Sridhar Sarnobat
2015年11月10日19:46
根据具体需要编码的字符,可以将其简化为perl -pe's /(\ W)/ sprintf(“ %%% 02X”,ord($ 1))/ ge',允许字母,数字和下划线,但编码其他所有内容。
– robru
16 Mar 4 '16 at 9:30
感谢您以上的回复!由于用例是针对curl的:也就是说::和/不需要编码,因此我在bashrc / zshrc中的最终功能是:perl -lpe's /([[A-Za-z0-9。\ /:] )/ sprintf(“ %%% 02X”,ord($ 1))/ seg
–范
12月16日4:32
#9 楼
如果您希望运行GET
请求并使用纯卷曲,只需将--get
添加到@Jacob的解决方案中。这里是一个示例:
#10 楼
这可能是最好的之一:after=$(echo -e "$before" | od -An -tx1 | tr ' ' % | xargs printf "%s")
评论
这对我有用,有两个附加功能:1.用-n替换-e以避免在参数末尾添加换行符;并且2.在printf字符串中添加'%%'以在每个字符串对的前面放置%十六进制数字。
–罗布·法根(Rob Fagen)
16-5-3在23:26
在将$前面的括号添加到$ =(echo -e ...
–罗马·罗恩·内斯特罗夫
16年9月1日在8:22
请解释这是如何工作的。 od命令并不常见。
–马克·斯托斯伯格
18-11-19在0:47
这不适用于OS X的od,因为它使用的输出格式与GNU od不同。例如printf aa | od -An -tx1 -v | tr \-打印----------- 61--61 ------------------ --------------------------------------使用OS X的od和-61-61使用GNU的od 。您可以将od -An -tx1 -v | sed's / * / / g; s / * $ //'| tr \%| tr -d \\ n与OS X的od或GNU od一起使用。 xxd -p | sed's /../%&/ g'| tr -d \\ n也做同样的事情,即使xxd不在POSIX中,而od是。
– nisetama
19年1月8日,11:59
尽管这可能有效,但它会转义每个字符
–查理
19-10-14在8:25
#11 楼
直接链接到awk版本:http://www.shelldorado.com/scripts/cmds/urlencode我用了很多年,它的工作原理就像一个魅力
评论
是否有获取UTF-8编码而不是ASCII的简单变体?
–avgvstvs
2015年10月2日,16:16
#12 楼
这是一个不调用任何外部程序的Bash解决方案:uriencode() {
s="${1//'%'/%25}"
s="${s//' '/%20}"
s="${s//'"'/%22}"
s="${s//'#'/%23}"
s="${s//'$'/%24}"
s="${s//'&'/%26}"
s="${s//'+'/%2B}"
s="${s//','/%2C}"
s="${s//'/'/%2F}"
s="${s//':'/%3A}"
s="${s//';'/%3B}"
s="${s//'='/%3D}"
s="${s//'?'/%3F}"
s="${s//'@'/%40}"
s="${s//'['/%5B}"
s="${s//']'/%5D}"
printf %s "$s"
}
评论
bash版本之间的行为有所不同。在RHEL 6.9上,bash为4.1.2,其中包括单引号。 Debian 9和bash 4.4.12可以使用单引号。对我来说,删除单引号会使它同时起作用。 s =“ $ {s //','/%2C}”
–安东·克鲁格(Anton Krug)
18年5月23日在15:28
我更新了答案以反映您的发现,@ muni764。
– davidchambers
18年5月23日在21:01
只是警告...这不会编码字符á
–diogovk
4月27日19:27
#13 楼
url=$(echo "" | sed -e 's/%/%25/g' -e 's/ /%20/g' -e 's/!/%21/g' -e 's/"/%22/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' -e 's/\*/%2a/g' -e 's/+/%2b/g' -e 's/,/%2c/g' -e 's/-/%2d/g' -e 's/\./%2e/g' -e 's/\//%2f/g' -e 's/:/%3a/g' -e 's/;/%3b/g' -e 's//%3e/g' -e 's/?/%3f/g' -e 's/@/%40/g' -e 's/\[/%5b/g' -e 's/\/%5c/g' -e 's/\]/%5d/g' -e 's/\^/%5e/g' -e 's/_/%5f/g' -e 's/`/%60/g' -e 's/{/%7b/g' -e 's/|/%7c/g' -e 's/}/%7d/g' -e 's/~/%7e/g')
这将对$ 1内的字符串进行编码并将其输出到$ url中。即使您愿意,也不必将其放在var中。 BTW并未包含sed for选项卡,因为它会把它变成空格
评论
我觉得这不是推荐的方法。
–科迪·格雷♦
2011年1月11日下午13:27
请解释一下您的感觉...。因为我所说的有效,并且已在多个脚本中使用了它,所以我知道它适用于列出的所有字符。因此,请解释为什么有人不使用我的代码并使用perl,因为其标题是“来自bash脚本的URLEncode”而不是perl脚本。
– manoflinux
2011-2-8在2:55
有时不需要珍珠溶液,因此可以派上用场
– Yuval Rimar
2011年10月31日在11:31
不建议这样做,因为黑名单是一种不好的做法,而且对unicode还是不利的。
– Ekevoo
2011-12-20 14:16
这是与cat file.txt兼容的最友好的解决方案
–mrwaim
18年1月20日在19:51
#14 楼
从外壳程序脚本使用php:value="http://www.google.com"
encoded=$(php -r "echo rawurlencode('$value');")
# encoded = "http%3A%2F%2Fwww.google.com"
echo $(php -r "echo rawurldecode('$encoded');")
# returns: "http://www.google.com"
http://www.php.net/manual/en/function.rawurlencode.php
http://www.php.net/manual/zh/function.rawurldecode.php
#15 楼
对于那些正在寻找不需要perl的解决方案的人,这里只需要hexdump和awk:url_encode() {
[ $# -lt 1 ] && { return; }
encodedurl="";
# make sure hexdump exists, if not, just give back the url
[ ! -x "/usr/bin/hexdump" ] && { return; }
encodedurl=`
echo $encodedurl | hexdump -v -e '1/1 "%02x\t"' -e '1/1 "%_c\n"' |
LANG=C awk '
== "20" { printf("%s", "+"); next } # space becomes plus
~ /0[adAD]/ { next } # strip newlines
~ /^[a-zA-Z0-9.*()\/-]$/ { printf("%s", ); next } # pass through what we can
{ printf("%%%s", ) } # take hex value of everything else
'`
}
从几个地方缝在一起网络和一些本地试验和错误。效果很好!
#16 楼
uni2ascii非常方便:$ echo -ne '你好世界' | uni2ascii -aJ
%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C
评论
这对于ASCII范围内需要引用的字符不起作用,例如%和空格(最后一个可以用-s标志纠正)
– Boldewyn
13年2月7日在14:59
#17 楼
如果您不想依赖Perl,也可以使用sed。有点混乱,因为每个字符都必须单独转义。创建具有以下内容的文件,并将其命名为urlencode.sed
s/%/%25/g
s/ /%20/g
s/ /%09/g
s/!/%21/g
s/"/%22/g
s/#/%23/g
s/$/%24/g
s/\&/%26/g
s/'\''/%27/g
s/(/%28/g
s/)/%29/g
s/\*/%2a/g
s/+/%2b/g
s/,/%2c/g
s/-/%2d/g
s/\./%2e/g
s/\//%2f/g
s/:/%3a/g
s/;/%3b/g
s//%3e/g
s/?/%3f/g
s/@/%40/g
s/\[/%5b/g
s/\/%5c/g
s/\]/%5d/g
s/\^/%5e/g
s/_/%5f/g
s/`/%60/g
s/{/%7b/g
s/|/%7c/g
s/}/%7d/g
s/~/%7e/g
s/ /%09/g
要使用它,请执行以下操作。
STR1=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f1)
STR2=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f2)
OUT2=$(echo "$STR2" | sed -f urlencode.sed)
echo "$STR1?$OUT2"
这会将字符串拆分为需要编码的部分,然后将其细分为需要编码的部分,然后将其缝合在一起。
您可以将其放入sh脚本中方便,也许需要一个参数进行编码,将其放在路径上,然后您可以调用:
urlencode https://www.exxample.com?isThisFun=HellNo
source
#18 楼
您可以在perl中模拟javascript的encodeURIComponent
。这是命令:perl -pe 's/([^a-zA-Z0-9_.!~*()'\''-])/sprintf("%%%02X", ord())/ge'
您可以在
.bash_profile
中将其设置为bash别名:alias encodeURIComponent='perl -pe '\''s/([^a-zA-Z0-9_.!~*()'\''\'\'''\''-])/sprintf("%%%02X",ord())/ge'\'
现在您可以通过管道插入
encodeURIComponent
:$ echo -n 'hèllo wôrld!' | encodeURIComponent
h%C3%A8llo%20w%C3%B4rld!
#19 楼
这是节点版本:uriencode() {
node -p "encodeURIComponent('${1//\'/\\'}')"
}
评论
如果字符串中还有其他在单引号之间引起无效的字符(例如单反斜杠或换行符),是否不会中断?
– Stuart P. Bentley
16年12月31日在19:09
好点子。如果我们要在Bash中转义所有有问题的字符,那么我们不妨直接执行替换操作并完全避免节点。我发布了仅Bash的解决方案。 :)
– davidchambers
17年1月1日,下午2:46
在页面其他地方找到的此变体通过从STDIN读取值来避免引用问题:node -p'encodeURIComponent(require(“ fs”)。readFileSync(0))'
–马克·斯托斯伯格
18年11月19日在1:02
#20 楼
简单的PHP选项:echo 'part-that-needs-encoding' | php -R 'echo urlencode($argn);'
#21 楼
问题是关于在bash中执行此操作,并且不需要python或perl,因为实际上只有一个命令可以完全满足您的要求-“ urlencode”。value=$(urlencode "")
这样也更好,例如,上面的perl答案不能正确编码所有字符。尝试使用从Word获得的长破折号,并且编码错误。
请注意,您需要安装“ gridsite-clients”才能提供此命令。
评论
我的bash版本(GNU 3.2)没有urlencode。您使用什么版本?
– Sridhar Sarnobat
2015年11月10日19:27
我有4.3.42,但是urlencode命令由“ gridsite-clients”提供。尝试安装它,应该没问题。
–迪伦
15年11月12日在12:45
因此,您的答案并不比要求安装其他任何东西(python,perl,lua等)的要好。
–西里尔·庞特维
17年7月27日在7:36
除了只需要安装一个实用程序而不是安装整个语言(和库)外,另外,它非常简单明了,可以看到它在做什么。
–迪伦
17年7月28日在13:29
首先,提供此命令的软件包/项目页面的链接将很有用。
– Doron Behar
3月27日10:26
#22 楼
Ruby,出于完整性考虑value="$(ruby -r cgi -e 'puts CGI.escape(ARGV[0])' "")"
#23 楼
另一个php方法:echo "encode me" | php -r "echo urlencode(file_get_contents('php://stdin'));"
评论
echo将附加一个换行符(十六进制0xa)。要停止它,请使用echo -n。
–马修堂
2014年10月10日上午10:01
#24 楼
这是执行此操作的POSIX函数:encodeURIComponent() {
awk 'BEGIN {while (y++ < 125) z[sprintf("%c", y)] = y
while (y = substr(ARGV[1], ++j, 1))
q = y ~ /[[:alnum:]_.!~*()-]/ ? q y : q sprintf("%%%02X", z[y])
print q}' ""
}
示例:
value=$(encodeURIComponent "")
源
#25 楼
这是我用于嵌入式系统的busybox灰壳的版本,我最初采用了Orwellophile的变体:urlencode()
{
local S=""
local encoded=""
local ch
local o
for i in $(seq 0 $((${#S} - 1)) )
do
ch=${S:$i:1}
case "${ch}" in
[-_.~a-zA-Z0-9])
o="${ch}"
;;
*)
o=$(printf '%%%02x' "'$ch")
;;
esac
encoded="${encoded}${o}"
done
echo ${encoded}
}
urldecode()
{
# urldecode <string>
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\x}"
}
#26 楼
这是使用Lua的单行转换,类似于blueyed的答案,除了所有RFC 3986未保留字符未编码(如此答案)之外:url=$(echo 'print((arg[1]:gsub("([^%w%-%.%_%~])",function(c)return("%%%02X"):format(c:byte())end)))' | lua - "")
此外,您可以需要确保将字符串中的换行符从LF转换为CRLF,在这种情况下,可以在百分比编码之前的链中插入
gsub("\r?\n", "\r\n")
。这是一种变体,非标准样式的application / x-www-form-urlencoded进行换行标准化,并将空格编码为“ +”而不是“%20”(可以使用类似的技术将其添加到Perl代码段中)。 />
url=$(echo 'print((arg[1]:gsub("\r?\n", "\r\n"):gsub("([^%w%-%.%_%~ ]))",function(c)return("%%%02X"):format(c:byte())end):gsub(" ","+"))' | lua - "")
#27 楼
Python 3基于@sandro从2010年以来的好答案:echo "Test & /me" | python -c "import urllib.parse;print (urllib.parse.quote(input()))"
测试%20%26%20 / me
#28 楼
安装了php后,我使用这种方式:URL_ENCODED_DATA=`php -r "echo urlencode('$DATA');"`
#29 楼
这是orwellophile答案的ksh版本,其中包含rawurlencode和rawurldecode函数(链接:如何为curl命令对数据进行urlencode?)。我没有足够的代表来发表评论,因此没有新评论。.#!/bin/ksh93
function rawurlencode
{
typeset string=""
typeset strlen=${#string}
typeset encoded=""
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) o=$(printf '%%%02x' "'$c")
esac
encoded+="${o}"
done
print "${encoded}"
}
function rawurldecode
{
printf $(printf '%b' "${1//%/\x}")
}
print $(rawurlencode "C++") # --> C%2b%2b
print $(rawurldecode "C%2b%2b") # --> C++
#30 楼
什么比URL解析URL更好?node -p "encodeURIComponent('$url')"
评论
超出操作问题范围。不重击,不卷曲。即使我确定节点可用也能很好地工作。
–西里尔·庞特维
17年7月27日在7:32
为什么要对此投票而不是python / perl答案?此外,这如何不响应原始问题“如何为curl命令添加数据?”。可以从bash脚本中使用它,并将结果提供给curl命令。
– Nestor Urquiza
17年7月31日在11:54
我也否决了其他人。问题是如何在bash脚本中执行此操作。如果使用其他语言(例如node / js,python或perl),则无需直接使用curl。
–西里尔·庞特维
17年8月3日在14:35
尽管我不费吹灰之力,但是此命令的问题在于它需要正确地转义数据才能在javascript中使用。像尝试使用单引号和一些反斜杠疯狂一样。如果要使用节点,则最好从stdin中读取内容,例如节点-p'encodeURIComponent(require(“ fs”)。readFileSync(0))'
– Michael Krelin-黑客
18年1月6日在18:01
如果要从STDIN传递数据,请谨慎使用@ MichaelKrelin-hacker的解决方案,请确保不要包含结尾的换行符。例如,echo | ...是错误的,而echo -n | ...取消换行符。
–马克·斯托斯伯格
18年11月19日,0:57
评论
另请参阅:如何在Shell中解码URL编码的字符串?用于非卷曲解决方案。另请参阅:如何在命令行上编码和解码百分比编码的字符串?