批量遍历变量并发送API请求

时间:2018-09-12 16:41:17

标签: batch-file curl cmd windows-console

我在使用Windows中的命令行从API获取一些数据时遇到了问题。基本上,这就是我想要做的:

1-从API(使用curl和jq)获取客户端列表,
2-将此列表保存为.txt(我想将其保存为变量,但是没有用),
3-遍历.txt中的客户端列表,并发送新的API请求以下载特定于该客户端的csv

前2步工作正常,但我停留在最后一环以遍历客户端。
这是我的代码:

setlocal ENABLEDELAYEDEXPANSION

Set tok=XXXXX
Set hURL="https://api.website.com/v2/clients?token=%tok%"
Set IDPath="C:\Users\My Self\subIDs.txt"
Set cuPath=%~dp0

del %IDPath%

curl -sS %hURL% | jq ".clients[].id" > %idPath%

FOR /F %%i in (%IDPath%) do (
    echo %%i
    Set subID=%%i
    Set rURL="https://api.website.com/v2/data?token=%tok%&subscriptionId=!subID!"
    curl -sS -o cuPath!subID!.csv !rURL!
)   

endlocal
pause

对我来说奇怪的是:
 -echo %% i返回:C:\ Users \ My
看起来路径中的空间是此循环的一个问题,但保存文件并没有引起任何问题,所以我有点迷路了
-我使用的是!subID!,据我了解,这是每次调整变量的唯一方法,但是当查看!rURL!变量的输出时,而< em>%tok%已成功传递为XXXXX,!subID!仍为!subID!
-我终于得到了一个卷曲:(6)无法解析主机:rURL

我对API,批处理或JSON完全陌生,尽管我觉得自己越来越近了,但我现在仍停留在最后。任何想法如何解决这个问题? 谢谢,

1 个答案:

答案 0 :(得分:0)

您的代码中有一些错误,以下代码已修复。

但是,由于您尚未指定jq ".clients[].id"返回的确切格式,因此我只能猜测它返回的是单个标记,字符之间没有任何空格,但是可能有前导或尾随空格。

因此,如果不是这种情况,则必须相应地设置FOR /F选项。

@echo off    
setlocal DisableDelayedExpansion

Set "tok=XXXXX"
Set "hURL=https://api.website.com/v2/clients?token=%tok%"
Set "rURL=https://api.website.com/v2/data?token=%tok%&subscriptionId="
Set "IDPath=C:\Users\My Self\subIDs.txt"

:: No need to delete %IDPath%, It will be overwrriten by the below redirection
curl -sS "%hURL%" | jq ".clients[].id" > "%IDPath%"

FOR /F "usebackq" %%i in ("%IDPath%") do (
    echo subID=%%i
    curl -sS -o "%~dp0%%i.csv" "%rURL%%%i"
) 

REM del "%IDPath%"

endlocal
pause

一些要点:

  • 您已为变量分配了在值中嵌入引号的变量,尽管这在您的特定情况下有效,但最佳实践是不要将引号嵌入变量值中,因此,最好不要使用Set hURL="https://..."使用Set "hURL=https://...",以后可以在实际使用引号时将其括在引号中:"%hURL%"

    考虑一下要访问不带引号的值的情况,那么如果您用set a="value"分配了值,则必须编写其他代码以从值中删除引号。但是通过set "a=value",您可以同时访问带引号("%a%")和不带引号(%a%)的值。

  • 您曾经使用Set cuPath=%~dp0而不带引号,它应该是Set "cuPath=%~dp0",但也不需要,您可以直接在循环中使用%~dp0

    随后,您在FOR循环中使用了cuPath,而没有对其进行扩展,也没有将cURL输出文件括在引号中。

  • 当用FOR /F读取文件内容时,如果的路径用引号引起来,则必须使用UseBackq选项来更改{{1 IN的}}子句不将其解释为文字字符串。

  • 根据您的操作,根本不需要延迟扩展。

    但是请注意,使用延迟扩展时必须格外小心。启用延迟扩展后,如果您的代码中包含FOR字符,则您可能在代码中使用的所有文字字符串(包括文件和url路径)都会被破坏。

    因此,最好在延迟扩展关闭时设置所需的变量和字符串,然后在启用延迟扩展时通过!语法访问它们。