situation: using batchscript retrieve values json.
i've got following batchscript:
@echo off echo enter npo.nl program-url : set url= set /p url= :: http://www.npo.nl/buitenhof/03-05-2015/vpwon_1232766/poms_vpro_850040 example setlocal enabledelayedexpansion /f "tokens=6 delims=/" %%a in ("%url%") ( /f "delims=" %%b in ('curl.exe -s http://e.omroep.nl/metadata/aflevering/%%a ^| jq.exe -r -r -s ".[1+index(\"^(\"): rindex(\"^)\")]"') ( /f "delims=" %%c in ('echo %%b ^| jq.exe -r .start') set ss=%%c /f "delims=" %%c in ('echo %%b ^| jq.exe -r .eind') set to=%%c /f "delims=" %%c in ('echo %%b ^| jq.exe -r .tijdsduur') set t=%%c echo start: !ss! echo end: !to! echo duration: !t! ) ) endlocal pause
what do?
upon having entered npo.nl program-url, first for-loop strips url down prid:poms_vpro_850040
. in second for-loop curl.exe retrieves json...:
parsemetadata({"status":"ok","version":"1.11.12","prid":"vpwon_1232766","titel":"schuim & as","aflevering_titel":"","info":"schuim & met jelle brandt corstius","ratio":"16:9","medium":"tv","gidsdatum":"2015-05-03","tijdsduur":"00:05:27","start":"00:23:13","eind":"00:28:40","url":"","webcast":1,"images":[{"size":"640x480","ratio":"4:3","url":"http:\/\/images.poms.omroep.nl\/image\/sx480\/c640x480\/606030.jpg"},{"size":"720x405","ratio":"16:9","url":"http:\/\/images.poms.omroep.nl\/image\/sx405\/c720x405\/606030.jpg"}],"omroepen":[{"naam":"vpro"}],"pubopties":["adaptive","h264_bb","h264_sb","h264_std"],"tt888":"ja","serie":{"srid":"vpwon_1232748","serie_titel":"buitenhof","serie_url":null},"sitestat":{"baseurl":"http:\/\/b.scorecardresearch.com\/p?c1=2&c2=17827132&ns_site=po-totaal","programurl":"uitzendinggemist.publiekeomroep.ondemand.tv.buitenhof.20150503","programurlpost":"category=uitzendinggemist&thema=informatief&po_source=video","baseurl_subtitle":"http:\/\/nl.sitestat.com\/klo\/po\/s","subtitleurl":"uitzendinggemist.publiekeomroep.ondemand.tv.player.tt888.buitenhof","subtitleurlpost":"category=uitzendinggemist&po_source=video&po_sitetype=webonly"},"reclame":"http:\/\/pubads.g.doubleclick.net\/gampad\/ads?_cookie_&impl=s&gdfp_req=1&env=vp&output=xml_vast2&unviewed_position_start=1&sz=_sz_&correlator=_correlator_&iu=\/9233\/_site_\/buitenhof&url=_url_&cust_params=genre%3dinformatief%2cnieuws%2factualiteiten%26dur%3d3284%26prid%3dvpwon_1232766%26srid%3dvpwon_1232748%26player%3d_player_","streamsense":{"episode":"buitenhof","program":"buitenhof","station":"nederland_1","sitestatname":"uitzendinggemist.publiekeomroep.ondemand.tv.buitenhof.20150503","sko":"true","sko_dt":"20150503","sko_pr":"buitenhof","sko_stid":"1","sko_ty":"tv.seg","sko_prid":"vpwon1232766","sko_t":"1210","sko_cl":"3284"}}) //epc
...and sends through pipe jq.exe removes non-json-data parsemetadata(
, ) //epc
, leaves single line intact. 2 reasons: 1) non-json-data present can't process anything, , 2) for-loops process 1 line @ time.
subsequent jq.exe's retrieve values specified objects without double quotes.
long curl.exe , jq.exe in same directory batchscript, or in %path%-variable, working fine:
start: 00:23:13 end: 00:28:40 duration: 00:05:27
now want call curl.exe , jq.exe map. 1 spaces in it:
set curl="c:\map spaces\curl.exe" set jq="c:\map spaces\jq.exe" @echo off echo enter npo.nl program-url : set url= set /p url= :: http://www.npo.nl/buitenhof/03-05-2015/vpwon_1232766/poms_vpro_850040 example setlocal enabledelayedexpansion /f "tokens=6 delims=/" %%a in ("%url%") ( /f "delims=" %%b in ('%curl% -s http://e.omroep.nl/metadata/aflevering/%%a ^| %jq% -r -r -s ".[1+index(\"^(\"): rindex(\"^)\")]"') ( /f "delims=" %%c in ('echo %%b ^| %jq% -r .start') set ss=%%c /f "delims=" %%c in ('echo %%b ^| %jq% -r .eind') set to=%%c /f "delims=" %%c in ('echo %%b ^| %jq% -r .tijdsduur') set t=%%c echo start: !ss! echo end: !to! echo duration: !t! ) ) endlocal pause
for 2nd for-loop causes problems:
'c:\map' not recognized internal or external command, operable program or batch file.
while 'echo %%x ^| %jq%'
work, seems '%curl% ^| %jq%'
doesn't. reason things go wrong 2 variables in pipe parsed.
well, no more pipe then:
set curl="c:\map spaces\curl.exe" set jq="c:\map spaces\jq.exe" @echo off echo enter npo.nl program-url : set url= set /p url= :: http://www.npo.nl/buitenhof/03-05-2015/vpwon_1232766/poms_vpro_850040 example setlocal enabledelayedexpansion /f "tokens=6 delims=/" %%a in ("%url%") ( /f "delims=" %%b in ('%curl% -s http://e.omroep.nl/metadata/aflevering/%%a') ( /f "delims=" %%c in ('echo %%b ^| %jq% -r -r -s ".[1+index(\"^(\"): rindex(\"^)\")]"') ( /f "delims=" %%d in ('echo %%c ^| %jq% -r .start') set ss=%%d /f "delims=" %%d in ('echo %%c ^| %jq% -r .eind') set to=%%d /f "delims=" %%d in ('echo %%c ^| %jq% -r .tijdsduur') set t=%%d echo start: !ss! echo end: !to! echo duration: !t! ) ) ) endlocal pause
now curl.exe , jq.exe each in for-loop. @ first seems work fine. 3 values echoed, things go wrong:
parse error: invalid numeric literal @ line 1, column 5 parse error: invalid numeric literal @ line 1, column 5 parse error: invalid numeric literal @ line 1, column 5 parse error: invalid numeric literal @ line 1, column 5 start: 00:23:13 end: 00:28:40 duration: 00:05:27
like said before; for-loops parse , process 1 line @ time. non-json-data //epc
on 2nd line causes for-loop start over, goes horribly wrong can see. that's reason pipe between curl , jq in code above. output 1 single line process. sadly didn't work either...sigh.
of course using temporary files last resort when curl , jq still in map spaces in it, prefer use variables, i'm trying solve pipe-issue. i've tried 'usebackq' in for-loop using backticks around command instead of single-quotes instance, no avail.
far haven't found solution. have explanation behaviour , how solve it?
thanks dave benham's answer on related issue i've found solution!
appeared specific /f bug in winxp, , guess what, here i'm still on winxp. fix main offender, curl-pipe-jq-for-loop, had put ^"
in front of and after entire command. entire batchscript, i've further improved:
@echo off cls :: npo json-extractor geschreven door reino wijnsma, 2015 (reino@degeelebosch.nl) set batchname=npo json-extractor set version=1.1 title %batchname% %version% set curl="c:\map spaces\curl.exe" set jq="c:\map spaces\jq-1.5rc1.exe" :check if exist %curl% ( if exist %jq% ( goto input ) else ( echo 'jq.exe' niet gevonden. echo. pause goto :eof ) goto input ) else ( echo 'curl.exe' niet gevonden. echo. pause goto :eof ) :input echo voer npo.nl programmalink in : set url= set /p url= :: http://www.npo.nl/buitenhof/03-05-2015/vpwon_1232766/poms_vpro_850040 bijvoorbeeld if "%url%"=="" goto :eof setlocal enabledelayedexpansion %%a in ("%url%") ( /f "delims=" %%b in ('^"%curl% -s http://e.omroep.nl/metadata/aflevering/%%~nxa ^| %jq% -r -r -s ".[1+index(\"(\"): rindex(\"^)\")]"^"') ( echo. echo json: /f "delims=" %%c in ('echo %%b ^| %jq% .') echo %%c echo. /f "tokens=1-3" %%c in ('echo %%b ^| %jq% -r "[.tijdsduur,.start,.eind] | @tsv"') ( echo tijdsduur: %%c if not "%%d"=="" ( set ss=%%d set to=%%e set /a "_ss=((1!ss:~0,2!-100)*3600)+((1!ss:~3,2!-100)*60)+(1!ss:~6,2!-100)" set /a "_to=((1!to:~0,2!-100)*3600)+((1!to:~3,2!-100)*60)+(1!to:~6,2!-100)" echo start: %%d (!_ss!s^) echo einde: %%e (!_to!s^) ) ) ) ) echo. endlocal goto input
important notes future reference:
jq-syntax: jq -r -r -s '.[1+index("("): rindex(")")]' cmd-shell: jq -r -r -s ".[1+index(\"(\"): rindex(\")\")]" for-loop: 'jq -r -r -s ".[1+index(\"(\"): rindex(\"^)\")]"' for-loop (path): '^"%jq% -r -r -s ".[1+index(\"(\"): rindex(\"^)\")]"^"'
- cmd-shell have escape double quotes line-feed \
.
- while 2 of closing parenthesis part of jq's syntax, 1 between double quotes not. when in for-loop, prevent for-loop closing, you'd have escape 1 ^
.
- when jq's executable path put in variable double quotes, circumvent winxp bug, you'd have put entire command between ^"
, because parenthesis considered special characters! workaround compatible vista , beyond. (see dostips.com)
Comments
Post a Comment