Board logo

标题: [文本处理] 【已解决】BAT代码从json文件只提取指定字段的值哪里有问题? [打印本页]

作者: _avatar_    时间: 2024-9-17 12:36     标题: 【已解决】BAT代码从json文件只提取指定字段的值哪里有问题?

想用批处理从json文件只提取指定字段的值,提取是成功了,但不知道为什么for语句不执行 do 里面的代码,是哪里写错了嘛?

cscript 部分的代码是从网上抄的,我对cscript执行代码完全小白。

这是 json 文件内容:
  1. {"media_type":2,"has_dash_audio":true,"is_completed":true,"total_bytes":37080115,"downloaded_bytes":37080115,"title":"七年级上册地理《世界气候类型的分布》人教版,提炼知识点,快速提分版,期中复习重点知识,帮助孩子归纳总结,地理逆袭考高分","type_tag":"116","cover":"http:\/\/i2.hdslb.com\/bfs\/archive\/db711b3345dc0f2c2e546d9586433484d19d0b78.jpg","video_quality":116,"prefered_video_quality":116,"guessed_total_bytes":0,"total_time_milli":415775,"danmaku_count":7,"time_update_stamp":1726490604122,"time_create_stamp":1726490595210,"can_play_in_advance":true,"interrupt_transform_temp_file":false,"quality_pithy_description":"1080P","quality_superscript":"60帧","variable_resolution_ratio":false,"cache_version_code":8130300,"preferred_audio_quality":0,"audio_quality":0,"avid":747920231,"spid":0,"seasion_id":0,"bvid":"BV1yC4y1E77K","owner_id":1865370698,"owner_name":"启梦学霸课堂","owner_avatar":"https:\/\/i2.hdslb.com\/bfs\/face\/c8722a5d4c191feae51be4966c5585b76f5b5173.jpg","is_charge_video":false,"verification_code":0,"page_data":{"cid":1319882112,"page":1,"from":"vupload","part":"七年级上册地理《世界气候类型的分布》人教版,提炼知识点,快速提分版,期中复习重点知识,帮助孩子归纳总结,地理逆袭考高分","link":"","rich_vid":"","vid":"","has_alias":false,"tid":208,"width":1080,"height":1920,"rotate":0,"download_title":"视频已缓存完成","download_subtitle":"七年级上册地理《世界气候类型的分布》人教版,提炼知识点,快速提分版,期中复习重点知识,帮助孩子归纳总结,地理逆袭考高分"}}
复制代码
这是批处理代码:
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. color a
  4. rem 从一个json文件中提取指定内容
  5. >"%tmp%\j.js" echo;var m=WSH.StdIn.ReadAll().match(/("title"):"[^"]+"/);if(m){WSH.StdErr.WriteLine(m[0]);}
  6. for /f %%i in ('type entry.json ^| cscript //B //nologo //e:jscript "%tmp%\j.js"') do (
  7.   set txt=%%i11111
  8.   echo !txt:9,-1!
  9. )
  10. pause
  11. exit
复制代码

作者: _avatar_    时间: 2024-9-17 12:37

结果是提取到了,但是显示完结果之后直接就到 pause 代码了,没有执行 do 里面的两行代码。
作者: ppll2030    时间: 2024-9-17 14:09

回复 2# _avatar_



红色为修改部分。JS获取内容后添加11111,并从第9个字符开始截取后面的字符


@echo off
setlocal EnableDelayedExpansion
color a
rem 从一个json文件中提取指定内容


>"%tmp%\j.js" echo;var m=WSH.StdIn.ReadAll().match(/("title"):"[^"]+"/);if(m)WSH.echo(m[0]);

for /f "delims=" %%i in ('type entry.json ^| cscript /nologo -e:jscript "%tmp%\j.js"') do (
  set "txt=%%i11111"
  echo !txt:~9,-1!
)
pause
exit
作者: _avatar_    时间: 2024-9-17 15:50

回复 3# ppll2030

非常感谢,原来是我对 //B 参数理解有误。

另外,不知道哪里可以看 WSH 这个对象相关的API手册? 看了您的代码之后,我发现只需要将 后面 if 里的修改成 WSH.echo() 输出,并且去掉 //B 参数就可以了。
所以,不知道在哪可以学习 WSH 这个对象的具体用法?

PS: !txt:9,-1! 那是写错了,漏了个 ~ 。
作者: czjt1234    时间: 2024-9-17 16:02

回复 4# _avatar_


本网站,首页,最下方,VBScript / JScript 在线参考
搜索 wscript对象
作者: _avatar_    时间: 2024-9-17 17:10

回复 5# czjt1234


    感谢指路,大概有点底了,慢慢学习。
作者: aloha20200628    时间: 2024-9-17 18:14

本帖最后由 aloha20200628 于 2024-9-17 18:21 编辑

回复 1# _avatar_

再给两个版本(分别存为批处理脚本文件 *.bat 运行),都用 cmd+jscript 混编方式,省略了临时文件。一版是直接采用 for 分隔器一步到位,二版是直接采用 jscript 正则匹配一步到位...

第一版 test-1.bat
  1. @set @v=1 /* &echo off
  2. for /f tokens^=2^delims^=:^" %%i in ('type "entry.json"^|cscript /nologo /e:jscript "%~f0"') do echo,%%i
  3. pause&exit/b */
  4. m=WSH.stdin.readall().match(/"title":"[^"]+"/), WSH.echo(m[0]), WSH.quit()
复制代码
第二版 test-2.bat
  1. @set @v=1 /* &echo off
  2. for /f %%i in ('type "entry.json"^|cscript /nologo /e:jscript "%~f0"') do echo,%%i
  3. pause&exit/b */
  4. m=WSH.stdin.readall().match(/[^"]+(?=","type_tag")/), WSH.echo(m[0]), WSH.quit()
复制代码

作者: _avatar_    时间: 2024-9-17 20:55

回复 7# aloha20200628


    多谢指教,学习啦。
作者: _avatar_    时间: 2024-9-17 21:08

回复 7# aloha20200628


    另外想问一下,代码中的 @set @v=1 作用是什么?
作者: aloha20200628    时间: 2024-9-17 21:49

回复 9# _avatar_

一种脚本代码与批处代码混编的关键,就是要在批处代码中找出能被自身语法接受的最短且最有效句式(桥段),以便接续其注释符,@set @v=1 就是 jscript 代码与批处代码混编的一种典型 ‘桥段’...

作者: _avatar_    时间: 2024-9-17 22:35

回复 10# aloha20200628


    就是 @set @v=1 其实本身没有什么作用,只是为了后面的 /* 不会报错而已,这样理解对吧。

    现在碰到了一个新问题,就是如果 json 获取到的结果的最后如果是中文字符,最后一个字符会乱码,类似于这篇帖子: http://bbs.bathome.net/viewthrea ... hlight=%C2%D2%C2%EB

    正在搜索看看有没有解决办法。
作者: aloha20200628    时间: 2024-9-17 23:47

回复 11# _avatar_

第一个问题:是
第二个问题:引用帖 http://bbs.bathome.net/viewthrea ... hlight=%C2%D2%C2%EB 中一楼的示例代码若存为 ansi 编码或 utf-8无头标 编码均可规避报错,用win7系统测试通过...

作者: _avatar_    时间: 2024-9-18 00:36

回复 12# aloha20200628


    并不是报错,是中文的最后一个字符会乱码。
    我用的 win10 ,倒是没有在win7中测试过。
作者: aloha20200628    时间: 2024-9-18 11:12

回复 13# _avatar_

引用帖中有建议在获取的中文数据后附加英文空白字符即可解...

作者: _avatar_    时间: 2024-9-18 19:08

回复 14# aloha20200628


    已经尝试过了,哪怕用正则往后多匹配几个英文字符也没用,除非是手动修改json文件,在中文字符的最后添加上一个英文字符。
    在jscript代码中添加英文字符也不生效,最后一个字符还是会乱码。
作者: aloha20200628    时间: 2024-9-18 21:43

本帖最后由 aloha20200628 于 2024-9-18 21:59 编辑

回复 15# _avatar_

你用7楼代码处理1楼示例文件的结果也会出现这种问题吗?我用win7/win8.1/win10测试均正常无误...

作者: _avatar_    时间: 2024-9-19 01:02

回复 16# aloha20200628


    你测试的时候  entry.json 文件应该是保存的 ANSI 编码吧,需要 entry.json 是 utf-8 编码测试,因为脚本的作用是自动读取 entry.json 文件来提取标题,而 entry.json 文件有很多,编码都是 utf8
作者: czjt1234    时间: 2024-9-19 09:29

  1. rem 另存为 ANSI 编码 bat
  2. ' & cls & cscript.exe /nologo /e:vbscript "%~f0" %* & pause & exit /b
  3. f = "entry.json"    '源文件
  4. u = "UTF-8"         '源文件的编码
  5. Set oWshShell = CreateObject("WScript.Shell")
  6. Set oFSO = CreateObject("Scripting.FileSystemObject")
  7. s = oFSO.GetParentFolderName(WScript.ScriptFullname)
  8. oWshShell.CurrentDirectory = s
  9. Set oRegExp = New RegExp
  10. oRegExp.Global     = True
  11. oRegExp.MultiLine  = True
  12. oRegExp.IgnoreCase = True
  13. oRegExp.Pattern    = """title"":"".*?"""
  14. Set oStream = CreateObject("ADODB.Stream")
  15. oStream.Type    = 2    'adTypeText
  16. oStream.Mode    = 3    'adModeReadWrite
  17. oStream.Charset = u
  18. oStream.Open()
  19. oStream.LoadFromFile f
  20. s = ""
  21. For Each oMatch In oRegExp.Execute(oStream.ReadText())
  22.     wsh.Echo oMatch.Value
  23. Next
复制代码

作者: aloha20200628    时间: 2024-9-19 14:13

本帖最后由 aloha20200628 于 2024-9-19 14:28 编辑

回复 15# _avatar_

调用 vbs/jscript 或下载或预装 grep/sed/awk/python/... 等都有方法可解,但在批处代码中直接调用 powershell 功能可以尽量简化这个问题,假设源文件 entry.json 是 utf-8 编码,以下代码存为 test.bat 运行...
  1. @echo off & powershell "$p=((gc 'entry.json' -raw -enc 'utf8') -match '[^"""]+(?=""","""type_tag""")');$matches[0]">"0.0"&set/p v=<"0.0"
  2. echo,%v%&del/q "0.0"&pause&exit/b
复制代码

作者: _avatar_    时间: 2024-9-20 20:26

回复 18# czjt1234


    你这个的确可以,vbs 我不懂,感谢指教!
作者: _avatar_    时间: 2024-9-20 20:28

回复 19# aloha20200628


    实际上我是在学习批处理,要解决问题本身我是有方法的,比如使用 nodejs。

    有打算学习一下 powershell 的,非常感谢指导!。




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2