简体   繁体   中英

Batch file stops after a series of pipes in XP

I have a following batch file that retrieves data from a database in JSON format, extracts numbers and stores them:

set server=http://login:password@host:port
set db=PostgreSQL%%20DB

del IDs.txt
echo Section1 >> IDs.txt
curl "%server%/%db%/Section1" | jq .[] | jq .[] >> IDs.txt
echo Section2 >> IDs.txt
curl "%server%/%db%/Section2" | jq .[] | jq .[] >> IDs.txt
echo Section3 >> IDs.txt
curl "%server%/%db%/Section3" | jq .[] | jq .[] >> IDs.txt
...

It works under Windows 8, but under Windows XP it stops after the first curl-jq line. There are no errors. Retrieving numbers works correctly, but only once.

I tried to replace curl-jq calls with

cmd /c "curl %server%/%db%/Section3 | jq .[] | jq .[] >> IDs.txt"

but it didn't help.

What is wrong? Is there a way to make this work in XP?

Thanks in advance.

Update: here are examples of output JSON:

{"ids":[80001]}

or

{"ids":[12001,12002,12003,43120]}

What I need is just to extract the numbers as a column:

80001

or

12001
12002
12003
43120

Perhaps this may help you?

@echo off

for /F "tokens=2 delims=[]" %%a in (input.txt) do (
   for %%b in (%%a) do (
      echo %%b
   )
)

Output example:

C:\> type input.txt
{"ids":[80001]}

C:\> test.bat
80001

C:\> type input.txt
{"ids":[12001,12002,12003,43120]}

C:\> test.bat
12001
12002
12003
43120

Rather than trying to use two invocations of jq , just use one. Also, it's generally best to quote your jq filters when they're given on the command line.

You're dumping the values in the ids property, so:

jq ".ids[]"

[EDIT: using double-quotes works here for both Windows and many other platforms, but on non-Windows platforms, single-quotes are usually the best bet.]

Try this script and see if it does what you want. Rather than depending on cURL to fetch the JSON, it uses an XMLHTTPRequest. Rather than depending on jq to deserialize the JSON, it uses the JavaScript JSON parser. And unlike Aacini's solution, it works the same regardless of whether the JSON is minified, beautified, whatever. Save it with a .bat extension.

@if (@CodeSection == @Batch) @then
@echo off & setlocal

set "server=http://login:password@host:port"
set "db=PostgreSQL DB"

>IDs.txt cscript /nologo /e:Jscript "%~f0" "%server%" "%db%"

goto :EOF
@end // end Batch / begin JScript hybrid chimera

var XHR = WSH.CreateObject('Microsoft.XMLHTTP'),
    htmlfile = WSH.CreateObject('htmlfile'),
    args = { 'server': WSH.Arguments(0), 'db': WSH.Arguments(1) },
    url = encodeURI(args.server + '/' + args.db + '/Section'),
    section = 0;

function fetch(url) {
    XHR.open('GET', url, true);
    XHR.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
    XHR.send('');
    while (XHR.readyState != 4) { WSH.Sleep(50); }
    return XHR.status == 200 ? XHR.responseText : '';
}

// import JSON method from htmlfile COM object
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var JSON = htmlfile.parentWindow.JSON;

// fetch JSON by section sequentially until 404 error
while ((response = fetch(url + ++section))) {
    WSH.Echo('Section' + section);
    ids = JSON.parse(response).ids;
    for (var i in ids) WSH.Echo(ids[i]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM