我正在尝试优化我的代码,并借用了一段特定的代码。我想删除sed所以我在主循环中没有使用任何外部进程。
function sendMsg () {
value=$(echo $1 | sed 's/ /%20/g;s/!/%21/g;s/"/%22/g;s/#/%23/g;s/\&/%26/g;s/'\''/%28/g;s/(/%28/g;s/)/%29/g;s/:/%3A/g;s/\//%2F/g');
str="http://www.xxxx.com/api.ashx?v=1&k=$Key&a=send&w=$value";
curl -s $str;
}
为了清晰起见,我编辑了这个。 $ value只是通过函数末尾的curl命令转换为适当的url输出。
虽然这很好用,但我最感兴趣的是尽可能快地处理,如果可以的话,不要求外部进程。
感谢您的评论到目前为止!
到目前为止我在这里:
function sendMsg () {
str="http://www.xxxx.com/api.ashx?v=1&k=$Key&a=send&w=";
curl -s $str --data-urlencode "$1";
}
我至少在正确的轨道上?
答案 0 :(得分:9)
首先,您的问题的答案:如果您正在进行单一替换或过滤,使用模式匹配会更快:
$ foo=${bar/old/new} # Faster
$ foo=$(sed 's/old/new/' <<<$bar # Slower
第一个不要求产生子shell,并运行sed
,然后将其替换回$foo
。但是,如果您这样做了近十几次,我相信使用sed
可能会更快:
value=$(sed -e 's/ /%20/g' \
-e 's/!/%21/g' \
-e 's/"/%22/g' \
-e 's/#/%23/g' \
-e 's/\&/%26/g' \
-e 's/'\''/%28/g' \
-e 's/(/%28/g' \
-e 's/)/%29/g' \
-e 's/:/%3A/g' \
-e 's/\//%2F/g'<<<$1);
请注意,由于每个替换命令都在其自己的行上,因此该语法更易于阅读。另请注意,<<<
消除了回声和管道的需要。
这只需要对sed
进行一次调用,而模式匹配必须多次完成。
但是,您应该使用--data
和--data-uuencode
而不是自己构建查询字符串:
$ curl -s http://www.xxxx.com/api.ashx \
--data v=1 \
--data k=$Key \
--data a=send \
--data-urlencode w="$value";
--data--urlencode
会为您编码$value
的值,因此您不必这样做。不幸的是,这个参数并不存在于curl
的所有版本中。它已于2008年1月在版本7.18.0中添加。运行curl --version
以查看您的版本:
$ curl --version # Life is good
curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
$ curl --version # David Sad
curl 7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
在尝试此操作时,即使我的curl --version报告为7.29.0
,我仍然会获得不支持的API版本ERROR&#39;
我无法测试你拥有的内容,但我决定尝试使用Jenkins服务器来查看是否可以设置构建描述。我确保描述中有空格,因此它需要--data-urlencoding
。这个命令有效:
$ curl --user dweintraub:swordfish \
--data Submit=Submit \
--data-urlencode description="This is my test descripition" \
http://jenkins.corpwad.com/jenkins/job/Admin-5.1.1/138/submitDescription
这就像我做的那样:
$ curl -user "dweintraub:swordfish http://jenkins.corpwad.com/jenkins/job/Admin-5.1.1/138/submitDescription?Submit=Submit&desciption=This%20is%20my%20test%20descripition"
请注意,--data
会为您添加问号。
(不,swordfish
不是我的密码)。
它并不像你的命令那么复杂,但它可能有助于指出你遇到问题的地方。你有用户名和密码吗?如果是,则需要--user
参数。
答案 1 :(得分:3)
如果必须这么做,那么产生多个sed
进程的开销可能会增加。在这种情况下,您可以改为使用以下行:
value=${1// /%20/}
value=${value//!/%21}
value=${value//\"/%22}
value=${value//\#/%23}
value=${value//&/%26}
value=${value//\'/%27}
value=${value//(/%28}
value=${value//)/%29}
value=${value//:/%3A}
value=${value//\//%2F}