处理 Windows 批处理脚本中的引号

发布于 2024-07-13 15:47:02 字数 235 浏览 2 评论 0原文

在 Windows 批处理文件中,当您执行以下操作时:

set myvar="c:\我的音乐和视频"

变量 myvar 存储时包含引号。 老实说我觉得这很愚蠢。 引号只是告诉字符串开始和结束的位置,而不是作为值本身的一部分存储。
我怎样才能防止这种情况发生?

谢谢。

In a Windows batch file, when you do the following:

set myvar="c:\my music & videos"

the variable myvar is stored with the quotes included. Honestly I find that very stupid. The quotes are just to tell where the string begins and ends, not to be stored as part of the value itself.
How can I prevent this from happening?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

尛丟丟 2024-07-20 15:47:02
set "myvar=c:\my music & videos"

请注意引号在 myvar 之前开始。 其实就是这么简单。
旁注: myvar 之后无法回显,除非它用引号引起来,因为 & 将被读取为命令分隔符,但它仍然可以用作路径。

“变量名称可以包含空格”下的 http://ss64.com/nt/set.html

set "myvar=c:\my music & videos"

Notice the quotes start before myvar. It's actually that simple.
Side note: myvar can't be echoed afterwards unless it's wrapped in quotes because & will be read as a command separator, but it'll still work as a path.

http://ss64.com/nt/set.html under "Variable names can include Spaces"

心在旅行 2024-07-20 15:47:02

这是正确的方法:

set "myvar=c:\my music & videos"

引号不会包含在变量值中。

This is the correct way to do it:

set "myvar=c:\my music & videos"

The quotes will not be included in the variable value.

谈情不如逗狗 2024-07-20 15:47:02

这取决于您想要如何使用该变量。 如果您只想使用不带引号的变量值,则可以使用延迟扩展和字符串替换,或者使用 for 命令:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

正如 andynormancx 所说,需要引号,因为字符串包含 <代码>&。 或者你可以用 ^ 来转义它,但我认为引号更干净一些。

如果您使用延迟扩展和字符串替换,您将获得不带引号的变量值:

@echo !myvar:"=!
>>> C:\my music & videos

您还可以使用 for 命令:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

但是,如果您想在命令中使用该变量,则必须使用带引号的值或将变量的值括在引号中:

  1. 使用字符串替换和延迟扩展来使用不带引号的变量值,但在命令中使用该变量:

    <前><代码>@echo 关闭
    SETLOCAL 启用延迟扩展

    设置 myvar="C:\我的音乐和视频"
    md %myvar%
    @echo !myvar:"=! 创建。

  2. 使用 for 命令使用以下值变量不带引号,但在命令中使用变量时必须用引号引起来:

    <前><代码>@echo 关闭
    设置 myvar="C:\我的音乐和视频"

    for /f "tokens=* delims=" %%P in (%myvar%) do (
    md“%%P”
    @echo %%P 已创建。

长话短说,实际上没有干净的方法来使用批处理文件中包含嵌入空格和/或 & 的路径或文件名。

It depends on how you want to use the variable. If you just want to use the value of the variable without the quotes you can use either delayed expansion and string substitution, or the for command:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

As andynormancx states, the quotes are needed since the string contains the &. Or you can escape it with the ^, but I think the quotes are a little cleaner.

If you use delayed expansion with string substitution, you get the value of the variable without the quotes:

@echo !myvar:"=!
>>> C:\my music & videos

You can also use the for command:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

However, if you want to use the variable in a command, you must use the quoted value or enclose the value of the variable in quotes:

  1. Using string substitution and delayed expansion to use value of the variable without quotes, but use the variable in a command:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:\my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  2. Using the for command to use the value of the variable without quotes, but you'll have to surround the variable with quotes when using it in commands:

    @echo OFF
    set myvar="C:\my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    

Long story short, there's really no clean way to use a path or filename that contains embedded spaces and/or &s in a batch file.

ㄟ。诗瑗 2024-07-20 15:47:02

Windows 命令解释器允许您在整个 set 命令周围使用引号(在从 NT 4.0 到 Windows 2012 R2 的每个 Windows NT 版本中均有效)

您的脚本应按如下方式编写:

@echo OFF

set "myvar=C:\my music & videos"

然后您可以根据需要在变量周围添加引号。

使用 CMD 提示符有时看起来很深奥,但命令解释器实际上在遵守其内部逻辑方面表现得非常可靠,您只需要重新思考一下即可。

事实上,set 命令根本不需要你使用引号,但是你进行变量赋值的方式以及不使用引号的 , 方法都会导致你的变量周围有额外的空格,这是很难处理的。调试脚本时请注意。

例如,下面的两种方法在技术上都是有效的,但是您可以有尾随空格,因此这不是一个好的做法:

set myvar=some text   
set myvar="some text" 

,下面的两种方法都是在 Windows 命令解释器中设置变量的好方法,但是双引号方法更优越:

set "myvar=Some text"
(set myvar=Some value)

例如 不做任何解释,该变量将准确地包含您正在查找的数据。

强文本但是,出于您的目的,只有引用的方法才能有效工作,因为您使用的是保留字符

因此,您可以使用:

set "myvar=c:\my music & videos"

但是,即使变量正确设置为该字符串,当您ECHO 命令解释器会将 & 符号解释为关键字,以指示后面有另一个语句。

因此,如果您想从变量中回显字符串,仍然需要告诉 CMD 解释器它是一个文本字符串,或者如果您不希望显示引号,则必须执行以下操作之一:

echo the variable with Quotes:

Echo."%myvar%"

echo变量不带引号:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

在上述两种情况下,您可以回显不带引号的字符串。 下面的示例输出:

C:\Admin>    Echo.%myvar:&=^&%
C:\my music & videos

C:\Admin>    <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>

The Windows command interpreter allows you to use the quotes around the entire set command (valid in every version of windows NT from NT 4.0 to Windows 2012 R2)

Your script should just be written as follows:

@echo OFF

set "myvar=C:\my music & videos"

Then you may put quotes around the variables as needed.

Working with the CMD prompt can seem esoteric at times, but the command interpreter actually behaves pretty solidly in obeying it's internal logic, you just need to re-think things.

In fact, the set command does not require you to use quotes at all, but both the way you are doing your variable assignment and the way the ,method of using no quotes can cause you to have extra spaces around your variable which are hard to notice when debugging your script.

e.g. Both of the below are technically Valid, but you can have trailing spaces, so it's not a good practice:

set myvar=some text   
set myvar="some text" 

e.g. Both of the below are good methods for setting variables in Windows Command interpreter, however the double quote method is superior:

set "myvar=Some text"
(set myvar=Some value)

Both of these leave nothing to interpretation the variable will have exactly the data you are looking for.

strong text However, for your purposes, only the quoted method will work validly because you are using a reserved character

Thus, you would use:

set "myvar=c:\my music & videos"

However, even though the variable IS correctly set to this string, when you ECHO the sting the command interpreter will interpret the ampersand as the keyword to indicate another statement follows.

SO if you want to echo the string from the variable the CMD interpreter still needs to be told it's a text string, or if you do not want the quotes to show you have to do one of the following:

echo the variable WITH Quotes:

Echo."%myvar%"

echo the variable WITHOUT Quotes:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

In the above two scenarios you can echo the string with no quotes just fine. Example output below:

C:\Admin>    Echo.%myvar:&=^&%
C:\my music & videos

C:\Admin>    <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>
小鸟爱天空丶 2024-07-20 15:47:02

使用jscript。

许多个月前(即大约 8 年),我正在开发一个大型 C++/VB6 项目,并且我有各种批处理脚本来完成部分构建。

然后有人向我指出了Joel Test,我特别迷恋第2点,并设置关于将我所有的小构建脚本合并到一个构建脚本中。 。 。

这几乎让我心碎,让所有这些小脚本在不同的机器上一起工作,设置略有不同,上帝啊,这太可怕了 - 特别是设置变量和参数传递。 它真的很脆弱,最轻微的东西就会破坏它,需要 30 分钟的调整才能恢复正常。

最终 - 我可能很顽固 - 我把所有东西都扔进去,大​​约一天用 JavaScript 重新编写了所有内容,用 CScript 从命令提示符运行它。

我没有回头。 虽然现在是 MSBuild 和 Cruise Control,但如果我需要做一些稍微涉及批处理脚本的事情,我会使用 jscript。

Use jscript.

Many moons ago (i.e. about 8 years give or take) I was working on a large C++/VB6 project, and I had various bits of Batch Script to do parts of the build.

Then someone pointed me at the Joel Test, I was particularly enamoured of point 2, and set about bringing all my little build scripts into one single build script . . .

and it nearly broke my heart, getting all those little scripts working together, on different machines, with slightly different setups, ye Gods it was dreadful - particularly setting variables and parameter passing. It was really brittle, the slightest thing would break it and require 30 minutes of tweaking to get going again.

Eventually - I can be stubborn me - I chucked the whole lot in and in about a day re-wrote it all in JavaScript, running it from the command prompt with CScript.

I haven't looked back. Although these days it's MSBuild and Cruise Control, if I need to do something even slightly involved with a batch script, I use jscript.

猫性小仙女 2024-07-20 15:47:02

尝试使用转义字符“^”,例如,

set myvar=c:\my music ^& videos

当您展开 myvar 时要小心,因为 shell 可能不会处理 & 。 作为字面意思。 如果上述方法不起作用,请尝试在字符串中插入插入符号:

set myvar=c:\my music ^^^& videos

Try using the escape character '^', e.g.

set myvar=c:\my music ^& videos

You'll have you be careful when you expand myvar because the shell might not treat the & as a literal. If the above doesn't work, try inserting a caret into the string too:

set myvar=c:\my music ^^^& videos
谜兔 2024-07-20 15:47:02

两种解决方案:

  1. 不要在路径名(目录或文件名)中使用空格或命令解释器特有的其他字符。 如果您仅使用字母、数字、下划线和连字符(以及扩展名前的句点来标识文件类型),您的脚本编写生活将变得无比简单。

    多年来我编写并收集了大量工具,包括一个可以重命名文件的 DOS 实用程序。 (它一开始只是从文件名中删除空格,但后来演变成替换文件名中的字符或字符串的东西,甚至是递归的。)如果有人感兴趣,我将启动并运行我长期被忽视的网站并发布此内容和其他。

    也就是说,变量不仅仅用于保存路径名,所以...

  2. 正如其他人已经指出的那样,SET“myvar=c:\my music &videos”是正确的解决方法对于这样一个变量值。 (是的,我说的是解决方法。我同意您最初倾向于引用该值(“我的音乐和视频”)更为直观,但正如他们所说,事实就是如此。

Two solutions:

  1. Don't use spaces or other characters that are special to the command interpreter in path names (directory or file names). If you use only letters, numbers, underscores, and hyphens (and a period before the extension to identify the file type), your scripting life will become immeasurably simpler.

    I have written and otherwise collected a plethora of tools over the years, including a DOS utility that will rename files. (It began as something that just removed spaces from filenames, but morphed into something that will replace characters or strings within the filenames, even recursively.) If anyone's interested, I will get my long-neglected web site up and running and post this and others.

    That said, variables aren't just for holding pathnames, so...

  2. As others have already pointed out, SET "myvar=c:\my music & videos" is the correct workaround for such a variable value. (Yes, I said workaround. I agree that your initial inclination to just quote the value ("my music & videos") is far more intuitive, but it is what it is, as they say.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文