如何从文本文件中解析用户名并将结果批量输出到另一个文本文件?
Posted
技术标签:
【中文标题】如何从文本文件中解析用户名并将结果批量输出到另一个文本文件?【英文标题】:How to parse usernames from a text file and output results to another text file with batch? 【发布时间】:2020-08-27 13:49:54 【问题描述】:我正在重新发布此内容,因为有人在没有时间让我进行适当编辑的情况下关闭了我之前的问题。我醒来发现它关门了。 :C 另外,我是该网站的新手。
我不确定如何完成我想做的事情。我会觉得使用批处理更舒服。因为,它是我比较熟悉的一种编程语言。请仅批处理脚本响应。
我需要将用户名(即 elocin_anagram LuceaterVR)解析为一个以逗号分隔的列表,然后放入另一个文本文件中。用户名是字符串中的显示名称。此字符串位于名为 subscriptions_first=100.txt 的文本文件中
这是字符串:
"_total":19,"subscriptions":["created_at":"2018-06-15T19:34:38Z","_id":"b7c42f6ce857162220e99533d3d6dc1ae11fac8d","sub_plan":"3000","sub_plan_name":"Channel Sub (❤ω❤)♡ ♡ ♡(elocin_anagram)","is_gift":false,"user":"display_name":"elocin_anagram","type":"user","bio":"personal bio here.","created_at":"2015-06-17T05:37:38Z","updated_at":"2020-05-11T05:51:58Z","name":"elocin_anagram","_id":"93742615","logo":"https://static-cdn.jtvnw.net/jtv_user_pictures/d37d128b-59b1-4015-9776-74866feb1d44-profile_image-300x300.png","sender":null,"created_at":"2019-07-10T00:04:45Z","_id":"6a26c5a56b39d142a6e25ad30589a1b923fbc1bb","sub_plan":"1000","sub_plan_name":"Channel Sub(≧◡≦) ♡ (elocin_anagram) ","is_gift":false,"user":"display_name":"LuckeaterVR","type":"user","bio":"","created_at":"2018-12-08T04:55:48Z","updated_at":"2020-04-24T01:44:56Z","name":"luckeatervr","_id":"400728304","logo":"https://static-cdn.jtvnw.net/jtv_user_pictures/322ba52a-655c-42a4-8cc9-7b875debd5dd-profile_image-300x300.png","sender":null,"created_at":"2020-01-16T01:23:17Z","_id":"17704f74767b5592c5fc221eca11a20579a8162c","sub_plan":"3000","sub_plan_name":"Channel Sub (❤ω❤)♡ ♡
我需要文本文件中的字符串输出如下所示:
elocin_anagram, LuckeaterVR, username3, username4, username5, ... Username100
省略号 (...) 表示文件中可能有 100 个用户名。
这将是我第一次尝试学习如何从文本文件中解析信息,并将其输出到另一个文本文件。我不知道如何做到这一点,非常感谢一些指导,所以我可以学习。我尝试查看各种教程和文档。他们都没有向我展示如何获得我想要的结果。用汤姆斯科特的话来说,“一旦你知道了一个东西的名字,你就可以用谷歌搜索它。”也许我没有使用正确的搜索词。 ¯_(ツ)_/¯(耸肩)
如果这篇文章有任何问题,请允许我在 24 小时内修复它,然后再关闭它。隔离后我的睡眠时间很奇怪。还有,怎么删除之前的帖子???
提前谢谢你。
【问题讨论】:
如果您编辑之前的问题,它将重新打开。但它不会被重新打开,因为它是错误类型的问题。请参阅for /?
在命令提示符下解析文本文件。请参阅set /?
了解如何操作变量。
我不明白你到底想做什么。您只是在制作一个将字符串发送到文本文件的批处理文件吗?
我想你会想使用for /f
。似乎您希望分隔符是逗号或分号(或可能两者兼有)。然后你需要从整个字符串中计算出你想要的标记。此方法要求分隔符的数量保持一致。如果您在 single 行上有很多用户名,这个建议可能完全错误。希望您的文件中每行有 1 个用户名。
我不知道 json。我们可以坚持使用批处理吗?
您的数据文件是 JSON 文件。
【参考方案1】:
批量执行这不是最佳方式,远非如此。还有其他命令行工具可以用来解析 JSON。
话虽如此,以下批处理文件完全符合您的要求(根据您的输入文件示例) - 它非常具体!
但是请注意,由于它是单行 JSON 文件,因此它会按原样读入环境变量,并且环境变量的最大长度有限制(我认为大约 32K - 不确定)。所以如果你的文件比这个大,它只会解析前(32K?)个字符。
@echo off
setlocal
set /p JSON_STR=<input_file.json
set display_names=
::call main function with %JSON_sTR% stripped of all quotes
call:get_display_names %JSON_STR:"=%
echo %display_names% > display_names.txt
exit /b
:get_display_names
::exit condition - remove extra ", " from beginning and return
if "%1"=="" set display_names=%display_names:~2% & goto:eof
::get first element (element is anything separated by ,)
set _elem=%1
::if "display_name" is found in _elem, assume it looks like "user:display_name:NAME_TO_EXTRACT"
::and get the 19th character and on as the display name, concatenating it to display_names
if not "%_elem:display_name=%"=="%_elem%" set display_names=%display_names%, %_elem:~19%
:: throw away %1 and move %2 to be the new %1 etc.
shift
::continue the loop (we are still inside the single call:get_display_names
goto get_display_names
【讨论】:
【参考方案2】:@echo off
setlocal
set "file=subscriptions_first=100.txt"
set "output=subscriptions_first=100_display_name.txt"
set "comma="
( for /f "delims=" %%A in (
'powershell -noprofile -command
"$content= get-content -path '%file%' -raw | convertfrom-json;"
"foreach ($subscription in $content.subscriptions) "
"$subscription.user.display_name"'
) do if not defined comma (
set /p "_=%%~A" <nul
set "comma=defined"
) else (
set /p "_=, %%~A" <nul
)
) > "%output%"
要获取 display_name 值,可以使用 Powershell 的convertfrom-json
。
名为file
的环境变量设置为文本文件的路径。 Powershell 会将文件的get-content
传递给convertfrom-json
。从创建的对象中访问每个user
,得到display_name
的值。回显的显示名称被重定向到由环境变量 output
指定的文件。
用这个极简的 json 文件美化结构测试。
"subscriptions": [ "user": "display_name": "elocin_anagram" , "user": "display_name": "LuckeaterVR" ]
输出:
elocin_anagram, LuckeaterVR
【讨论】:
【参考方案3】:如前所述,批处理并不是这项任务的最佳解决方案(甚至可能是最差的解决方案之一),但它并非完全无能为力。第一个 for
循环将字符串拆分为单个元素(默认拆分为空格、TAB、COMMA 等分隔符),第二个 for
过滤所需元素并提取正确的部分:
@echo off
setlocal enabledelayedexpansion
set "string="_total":19,"subscriptions":["created_at":"2018-06-15T19:34:38Z","_id":"b7c42f6ce857162220e99533d3d6dc1ae11fac8d","sub_plan":"3000","sub_plan_name":"Channel Sub (❤ω❤)♡ ♡ ♡(elocin_anagram)","is_gift":false,"user":"display_name":"elocin_anagram","type":"user","bio":"personal bio here.","created_at":"2015-06-17T05:37:38Z","updated_at":"2020-05-11T05:51:58Z","name":"elocin_anagram","_id":"93742615","logo":"https://static-cdn.jtvnw.net/jtv_user_pictures/d37d128b-59b1-4015-9776-74866feb1d44-profile_image-300x300.png","sender":null,"created_at":"2019-07-10T00:04:45Z","_id":"6a26c5a56b39d142a6e25ad30589a1b923fbc1bb","sub_plan":"1000","sub_plan_name":"Channel Sub(≧◡≦) ♡ (elocin_anagram) ","is_gift":false,"user":"display_name":"LuckeaterVR","type":"user","bio":"","created_at":"2018-12-08T04:55:48Z","updated_at":"2020-04-24T01:44:56Z","name":"luckeatervr","_id":"400728304","logo":"https://static-cdn.jtvnw.net/jtv_user_pictures/322ba52a-655c-42a4-8cc9-7b875debd5dd-profile_image-300x300.png","sender":null,"created_at":"2020-01-16T01:23:17Z","_id":"17704f74767b5592c5fc221eca11a20579a8162c","sub_plan":"3000","sub_plan_name":"Channel Sub (❤ω❤)♡ ♡ "
for %%a in (!string!) do (
for /f "tokens=3 delims=:" %%b in ('echo %%a^|find "display_name"') do (
echo found %%~b
set "users=!users!, %%~b"
)
)
echo %users:~2
注意:这适用于您的示例字符串。但是有一个行长限制,当有更多用户时你可能会达到这个限制(你说的是“100”)
【讨论】:
以上是关于如何从文本文件中解析用户名并将结果批量输出到另一个文本文件?的主要内容,如果未能解决你的问题,请参考以下文章