简体   繁体   English

在 Windows cmd 中,如何用换行符替换 " 特殊字符?

[英]In Windows cmd, how to replace the " special character with a line break?

Just to be thorough, I'll state here my whole project and what I'm aiming at.为了彻底起见,我将 state 在这里我的整个项目和我的目标。

I intend to adapt a shell script to work in Windows cmd, as this is intended for people who are not going to have some sophisticate language available.我打算修改 shell 脚本以在 Windows cmd 中工作,因为这适用于不会使用一些复杂语言的人。

for g in $(curl -Ls https://api.chess.com/pub/player/hikaru/games/archives | jq -rc ".archives[]") ; do curl -Ls "$g" | jq -rc ".games[].pgn" ; done >> games.pgn

For some reason, Chess.com's API doesn't have a very important feature that Lichess' does, to export all games of a single player, so what I can do manually is to use https://api.chess.com/pub/player/hikaru/games/archives to export all available monthly archives and then hit the API for each one of them.由于某种原因,Chess.com 的 API 没有 Lichess 的一个非常重要的功能,即导出单个玩家的所有游戏,所以我可以手动使用https://api.chess.com/pub/player/hikaru/games/archives导出所有可用的每月档案,然后为每个档案点击 API。 ( hikaru inside this will be a set variable, it's the nickname of the desired player to export). (其中的hikaru将是一个集合变量,它是要导出的所需玩家的昵称)。

The result for this command is something like此命令的结果类似于

{"archives":["https://api.chess.com/pub/player/hikaru/games/2015/11","https://api.chess.com/pub/player/hikaru/games/2015/12","https://api.chess.com/pub/player/hikaru/games/2016/02","https://api.chess.com/pub/player/hikaru/games/2016/03","https://api.chess.com/pub/player/hikaru/games/2016/04","https://api.chess.com/pub/player/hikaru/games/2016/05"]}

to which I only have to append /pgn to get the desired result.我只需要 append /pgn即可获得所需的结果。

Obviously, cmd doesn't have jq available, so this involves "parsing" the string inside a batch file.显然,cmd 没有可用的jq ,因此这涉及到“解析”批处理文件中的字符串。

I figured if I just could replace every occurrence of " with a linebreak and echo the results, I could then use find (or findstr ) to easily get a list of lines that only would need to be prefaced with curl and appended with /pgn to get my final result.我想如果我可以用换行符替换每次出现的"并回显结果,然后我可以使用find (或findstr )轻松获取只需要以curl开头并附加/pgn到的行列表得到我的最终结果。

The big question is: how do I replace " with a linebreak in cmd? I found a few answers, but none of them seems to work with a special character, part of the problem is that I also didn't understand these answers enough to try and adapt them.最大的问题是:我如何用 cmd 中的换行符替换" ?尝试调整它们。

A second way of perhaps achieving the same result would be replacing [ , ] and , with line breaks, but then I would also have to worry with deleting the final " to append /pgn , so if I'm able to do the former, it would be cleaner.可能实现相同结果的第二种方法是用换行符替换[ , ],但是我也不得不担心删除最后的"到 append /pgn ,所以如果我能够做到前者,它会更干净。

in batch/cmd, a for loop is used to process a list (separated by default delimiters like space, tab, comma).在批处理/cmd 中, for循环用于处理列表(默认分隔符,如空格、制表符、逗号)。 So just replace [ and ] with a space or comma, and you have a nice list to split.因此,只需将[]替换为空格或逗号,您就有了一个很好的拆分列表。 Finally, use find to filter the output to the relevant parts and you're done:最后,使用find将 output 过滤到相关部分即可:

@Echo off
setlocal

set "string={"archives":["https://api.chess.com/pub/player/hikaru/games/2015/11","https://api.chess.com/pub/player/hikaru/games/2015/12","https://api.chess.com/pub/player/hikaru/games/2016/02","https://api.chess.com/pub/player/hikaru/games/2016/03","https://api.chess.com/pub/player/hikaru/games/2016/04","https://api.chess.com/pub/player/hikaru/games/2016/05"]}"


set "string=%string:[= %"
set "string=%string:]= %"
for %%a in (%string%) do echo %%~a|find "/"

Output: Output:

https://api.chess.com/pub/player/hikaru/games/2015/11
https://api.chess.com/pub/player/hikaru/games/2015/12
https://api.chess.com/pub/player/hikaru/games/2016/02
https://api.chess.com/pub/player/hikaru/games/2016/03
https://api.chess.com/pub/player/hikaru/games/2016/04
https://api.chess.com/pub/player/hikaru/games/2016/05

(in case you wonder: the tilde in echo %%~a removes surrounding quotes) (如果您想知道: echo %%~a中的波浪号会删除周围的引号)

Stephan's answer gave me the directions I needed to research more and build my own solution. Stephan 的回答为我提供了进一步研究和构建自己的解决方案所需的方向。 This is not the final script to my project, but it does solve every problem presented in my original question:这不是我项目的最终脚本,但它确实解决了我最初的问题中提出的所有问题:

@echo off
setLocal enabledelayedexpansion
for /f "delims=" %%a in (input.txt) do (
    for %%b in (%%a) do (
    set string=%%b
    set "string=!string:[=,!"
    set "string=!string:]=,!" 
    echo !string!>>replaced.txt
    )
)
for /f "delims=" %%c in (replaced.txt) do (
    for %%d in (%%c) do (
    echo %%~d>>echo.txt
    )
)
for /f %%e in (echo.txt) do echo curl %%~e/pgn|find ".">>list.txt

I basically run 3 sets of loops, the first one loads my input (this could not be done via set because there's a size limit, using a nested loop works around that) and replaces [ and ] for commas.我基本上运行 3 组循环,第一个加载我的输入(这不能通过set完成,因为有大小限制,使用嵌套循环可以解决这个问题)并替换[]为逗号。

The second loop sorts again the output.第二个循环再次对 output 进行排序。 This is done basically to trim unwanted characters from the first and last line.这基本上是为了修剪第一行和最后一行中不需要的字符。

The last loop generates a list of curl commands that will later be executed into a PGN file (which is a chess file).最后一个循环生成一个 curl 命令列表,这些命令稍后将被执行到 PGN 文件(这是一个国际象棋文件)中。


This ends the scope of the question, but since my project wasn't that complex, I'll present it's final version, which improves on Compo's answer, in case someone else stumbles upon this question:这结束了问题的 scope,但由于我的项目并不复杂,我将展示它的最终版本,它改进了 Compo 的答案,以防其他人偶然发现这个问题:

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::             Chess.com and Lichess API Scraper               ::
::                  Author: fabiorzfreitas                     ::
:: Extract all games from a player from Chess.com and Lichess  ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: This tool uses Chess.com and Lichess APIs to extract all games from a given player. ::

@echo off
setLocal enabledelayedexpansion

echo.
echo.
echo.
echo All input must be lowcase!
echo.
echo You can skip the input bellow by pressing Enter
echo.
echo.
echo.
set /p lichess="Input Lichess nickname and press Enter: "
set /p chess="Input Chess.com nickname and press Enter: "
echo.

:Lichess
if not defined lichess goto :Chess

curl https://lichess.org/api/games/user/%lichess% >> Games.pgn

:Chess
if not defined chess goto :End

(for /f "usebackq tokens=2 delims=[]" %%g in (`curl https://api.chess.com/pub/player/%chess%/games/archives`) do (
    for %%h In (%%g) do curl "%%~h/pgn" >> Games.pgn
    )
)

:End
exit

Based upon your own answer, it seems as if you could remove at least one of those steps by using the brackets [ and ] , as delimiters.根据您自己的回答,您似乎可以通过使用括号[]作为分隔符来删除这些步骤中的至少一个。

You could also nest a for loop within another instead of having individual ones and writing to files.您还可以在另一个循环中嵌套一个 for 循环,而不是使用单独的循环并写入文件。

Here it is as a single line :这是一个单行

@(For /F "UseBackQ Tokens=2 Delims=[]" %%G In ("input.txt") Do @For %%H In (%%G) Do @Echo curl.exe "%%~H/pgn") 1>"list.txt"

To do it directly in :直接在中执行此操作:

(For /F "UseBackQ Tokens=2 Delims=[]" %G In ("input.txt") Do @For %H In (%G) Do @Echo curl.exe "%~H/pgn") 1>"list.txt"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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