虚度光阴的一整天:Windows下如何去掉echo中的双引号
在 《每天进步一点点:学习使用Graphviz》一文中,我介绍了初学者了解&使用graphviz最简便的方法,那就是直接使用命令行。
(图源 :pixabay)
比如,最简单的生成最简单的“Hello World”关系图,命令如下:
echo 'digraph { Hello -> World }' | dot -Tsvg > output.svg
但是这条命令在Linux下或许会准确无误地执行,在Windows下,却只生成了一个0字节大小的svg文件,内容嘛,自不必多言,当然是空的。
好吧,我还曾试图打开它,得到如下提示信息:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
从代码上,貌似并没有什么问题呀?哪里出错了呢?上述代码的意义就是将echo语句的输出作为输入传递给dot指令,然后在把输出重定向给output.svg。
其中涉及到输入输出重定向的两个操作分别为|(管道操作符)以及>(输出重定向),想对这个两个深入了解的请参考文末链接。
既然我们不清楚哪里出错,那么就逐步调试呗,我们首先测试管道前边的部分,echo 'digraph { Hello -> World }',期望其输出digraph { Hello -> World }。
然而在Windows命令行执行上述指令,却发现什么输出都没有。
仔细研究会发现在语句echo 'digraph { Hello -> World }'中>被识别为输出重定向,它把ECHO输出的内容,重定向到一个名为World的文件中,这显然不是我们需要的结果。
测试使用转义字符^来对>进行转义,亦即echo 'digraph { Hello -^> World }',倒是可以输出'digraph { Hello -> World }',但是传递给dot依然失败,果断放弃。
这时我想到,既然单引号中的内容会被转义,那么如果使用双引号呢?亦即echo "digraph { Hello -> World }" | dot -Tsvg > output.svg
结果却得到如下提示:
Error: <stdin>: syntax error in line 1 near '"'
看一下echo语句的输出,为"digraph { Hello -> World }",也就是说dot程序不接受""(双引号)作为输入(可以直接执行dot -Tsvg,并输入上述内容验证)。
现在,问题进一步简化,就变成了,如何脱掉echo输出中的双引号。
原本以为这并不会是个问题,毕竟Linux下echo支持很多参数,而且输出的内容直接是脱双引号的,结果折腾半天才发现,Windows的echo弱到爆!指望参数啥的来搞定,那是不可能啦。
通过参数转换去双引号
经过我不懈努力,找到几个去掉双引号的方案,多数是使用批处理文件调用时通过去掉参数的双引号来实现的:
%~1 Expands %1 and removes surrounding quotation marks.
比如以下这个例子(来自文末链接):
@echo off
setlocal
set mystring="this is some quoted text"
echo mystring=%mystring%
call :dequote %mystring%
echo ret=%ret%
endlocal
goto :eof
:dequote
setlocal
rem The tilde in the next line is the really important bit.
set thestring=%~1
endlocal&set ret=%thestring%
goto :eof
但是我们把代码中字符串换成我们需要的"digraph { Hello -> World }",输出却不是我们想要的样子:
其实对于上述代码,我们可以简化成如下形式:
@setlocal
@set thestring=%~1
@echo %thestring%
@endlocal
将其保存为myecho.bat,并以类似如下形式调用:
myecho "digraph { Hello }" | dot
是可以得到正确输出的
但是依然无法正确处理"digraph { Hello -> World }"。
通过搜索替换去双引号
另一种方案是通过搜索替换来去掉双引号。
其本质是基于可以使用%var:x=y%构造将所有x替换为y
示例代码如下(来自文末链接):
set I="Text in quotes"
rem next line replaces" with blanks
set J=%I:"=%
echo original %I%
rem next line replaces the string 'in' with the string 'without'
echo stripped %J:in=without%
代码不做更多解读了,同样处理不了我们的问题。
通过set的提示语
无意中又发现一种方案,这个就太牛了,示例如下:
echo | set /p=";lt;h1;gt;Hello;lt;/h1;gt;"
输出如下:
这段代码我敢保证99%的人看不懂。
我们通过set /?来查看以下帮助信息(部分内容如下):
我们会发现/p的作用是带出一串提示信息,然后手动输入从终端变量值。这时候echo以及|(管道操作)起的作用是模拟终端输入回车。
如果后边继续跟|,那么会因为没有额外输入信息,所以提示信息被作为输入传递给之后的程序。
所以以下语句是可以正常工作的:
echo | set /p="digraph { Hello -> World }"| dot -Tsvg > output.svg
我们会得到如下图形:
也可以使用如下语句调试一下:
echo | set /p="digraph { Hello -> World }"| dot
不得不感慨一下,互联网上真的有能人啊!我去理解都费了如此周转,那么这是什么脑回路才能想出来的办法?
然后又不得不感慨一下自己,得多么无聊地浪费大把的时间研究这个?明明只有初学者测试才能用到命令行直接echo的方式。还有就是既然Windows的echo不好用,写一个简单的echo,大概也用不了多久吧!
又是虚度光阴的一整天!😡
相关链接
- 每天进步一点点:学习使用Graphviz
- 如何在Windows批处理文件的ECHOed字符串中去除引号?
- windows - 如何从 Windows 批处理文件中的 ECHO 字符串中去除引号?
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/echo
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/call
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/set_1
- https://ss64.com/nt/set.html
- https://ss64.com/nt/syntax-args.html
- https://ss64.com/nt/syntax-redirection.html
Leave 虚度光阴的一整天:Windows下如何去掉echo中的双引号 to:
Read more #cn posts
Best Posts From oflyhigh
We have not curated any of oflyhigh's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.