【问题标题】:Batch %1 get path with whitespace批处理 %1 获取带空格的路径
【发布时间】:2015-02-17 22:48:44
【问题描述】:

我已将批处理文件设置为默认打开 .txt 文件。在较早的问题中,我发现 %1 给了我实际调用批处理文件的文件的路径。问题是:如果文件名包含空格,它会被解释为多个参数。

例子:

打开文件“C:\Users\Desktop\space true.txt”

%1 给出:“C:\Users\Desktop\space”,然后 %2 给出:“true.txt”

如何在不尝试执行循环以尝试通过组合 %1%2%3%4... 来获取完整路径的情况下仅获取包含名称和空格的完整文件路径...

更新-----------

很抱歉,有一个错过的通信。下面的代码正在运行。诀窍是用“%*”代替“%1”

这里是代码:

@echo on
set var= "%*"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar"%var%
pause

我做了整个更改路径,因为我双击的文件和批处理文件位于不同的目录中。我不得不把它改成这个。

更新 2 --------------

最适合我的解决方案来自这位优秀的德本汉先生。

@echo off
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*

我唯一的抱怨是,有一种情况,%* 没有返回带引号的路径。所以我正在寻找最终的解决方案。像这样的东西"%~*" 但这不起作用。

提前致谢

【问题讨论】:

  • 那么请阅读我的回答。它解释了为什么它不起作用。

标签: batch-file whitespace


【解决方案1】:

以下内容不太正确 - 我认为文件关联会像拖放一样在文件名周围加上引号。但我错了

这一行是你的问题的根源:

set var= "%*"

当文件被拖到您的批处理脚本上时,或者如果双击一个文本文件,任何包含空格的文件名都会自动括在引号内。

当您添加自己的附加引号时,它会破坏引号的目的 - 不再引用空格。

例如,像"name with space.txt" 这样的字符串被视为单个参数,但加上引号,""name with space.txt"" 变成三个参数。

不需要您的 var 变量。您可以在 START 命令中直接使用%*

@echo on
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*
pause

如果传递了多个文件,我不确定上述是否能正常工作。我怀疑您可能想要以下内容:

@echo on
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F
pause

有一个潜在的问题。 Windows 有一个错误,即包含& 的文件名不会按应有的方式自动引用。请参阅"Droplet" batch script - filenames containing ampersands 了解更多信息。

编辑 - 以下应该可以工作

好的,我做了一些测试,我相信你最好的办法是修改与 .txt 文件关联的命令。

我通过命令行测试了关联更改。这必须通过具有管理员权限的提升命令提示符来完成。在我的机器上,我转到开始菜单,单击“所有程序”,单击“附件”文件夹,右键单击“命令提示符”,然后选择“以管理员身份运行”,然后单击“是”以允许程序制作改变系统。

下面的命令会显示需要修改的文件类型

assoc .txt

在我的机器上它报告.txt=txtfile,所以txtfile是必须使用FTYPE修改的。

我相信以下内容应该适合您:

ftype txtfile="C:\pathToYourScrpt\yourScript.bat" "%1"

显然您需要修复批处理脚本的路径:-)

一旦您进行了更改,每次通过文件关联调用您的脚本时,都会自动引用文件名。

然后您的批处理脚本可能如下所示,并且无论如何调用它都应该可以工作(文件名包含& 但没有空格的拖放除外):

@echo off
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F

在我看来,您应该能够消除批处理脚本并配置 FTYPE TXTFILE 以直接打开您的 java 编辑器。我应该这样想:

ftype txtfile="c:\pathToJava\javaw.exe" -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%1"

【讨论】:

  • 感谢您的回答。你在我有机会更新 op 之前发布了。我需要的修复只是“%*”。但是正如您所说,我发现,将文件拖到批处理上时,引号实际上会弄乱一切。但是当正常打开时, %* 返回不带引号的路径,所以我需要它们。好吧,我看到“%~1”修复了引用问题,但我无法让“%~*”工作......而且我必须将它传递给一个临时变量,因为批处理文件和实际.txt 文件位于不同的目录中..
  • 好的。嗯,我印象深刻。您的代码运行良好,除了:没有引号的 %* 仅在我将 .txt 文件拖到批处理文件时才有效。如果我双击 .txt,路径字符串不包含引号,这会弄乱 java。我看到像“%~1”这样的简单“~”可以解决这些问题,但这不适用于“%~*”。有什么想法吗??
【解决方案2】:

调用批处理文件时,如果参数中有空格,则必须将参数括在引号中。

例如:Batch.cmd "C:\Users\Desktop\space true.txt"

埃里克

【讨论】:

  • 好吧,我不亲自调用批处理文件。就像我说的,我已将批处理文件设置为处理 .txt 文件时要打开的标准“程序”......我现在只是双击 .txt 文件...所以我无法将路径放在“”...
【解决方案3】:
%*

这是一个字符列表。

&    seperates commands on a line.

&&    executes this command only if previous command's errorlevel is 0.

||    (not used above) executes this command only if previous command's errorlevel is NOT 0

>    output to a file

>>    append output to a file

<    input from a file

|    output of one command into the input of another command

^    escapes any of the above, including itself, if needed to be passed to a program

"    parameters with spaces must be enclosed in quotes

+ used with copy to concatinate files. E.G. copy file1+file2 newfile

, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,

%variablename% a inbuilt or user set environmental variable

!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command

%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.

%* (%*) the entire command line.

%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.

【讨论】:

  • 好的非常有用。谢谢!我会尽快将其作为解决方案来实施 xD
  • 我可以请您看一下我在更新操作中的代码吗?我现在不得不改变它好几次,因为我发现了越来越多的小错误,比如白人步伐和双引号和其他东西。看来你是个很懂 cmd 命令的人,也许你可以给我一个反馈并纠正任何愚蠢的错误?
【解决方案4】:

您的问题实际上是您的 set 命令的语法错误。在一个批次 文件,设置命令如下所示:

set "var=%1"

这将为您提供与收到的完全相同的变量。如果用户引用它, 那么变量的值将在其周围加上引号。要删除引号, 你可以在号码前加上~

set "var=%~1"

请注意引号如何围绕整个作业,而不仅仅是围绕 您分配的值。不是set var="%1"

如果你使用set var= "%*",你还没有真正解决根本问题 你的语法是错误的。另外,通常你真的想要%1 而不是 整个命令行。

这是一个测试各种引用行为的示例脚本:

@echo off
set var="%*"
echo 1.  var="%%*"  --^> [%var%]  (wrong)

set "var=%*"
echo 2.  "var=%%*"  --^> [%var%]

set "var=%1"
echo 3.  "var=%%1"  --^> [%var%]

set "var=%~1"
echo 4.  "var=%%~1" --^> [%var%]

set "var=%~2"
echo 5.  "var=%%~2" --^> [%var%]

set "var=%~3"
echo 6.  "var=%%~3" --^> [%var%]

这是该脚本的输出。注意 arg1、arg2 和 arg3 是如何全部的 引用:

C:\batch> all_args.cmd "arg 1" "this is arg 2" "arg 3"

1.  var="%*"  --> [""arg 1" "this is arg 2" "arg 3""]  (wrong)
2.  "var=%*"  --> ["arg 1" "this is arg 2" "arg 3"]
3.  "var=%1"  --> ["arg 1"]
4.  "var=%~1" --> [arg 1]
5.  "var=%~2" --> [this is arg 2]
6.  "var=%~3" --> [arg 3]

您可以看到数字 4、5 和 6 正确地取出了它们引用的参数 并将值保存到var中。您通常希望保存不带引号的参数,然后在脚本中使用它时引用它。换句话说,你的脚本应该是这样的:

@echo on
set "var=%~1"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" "%var%"
pause

【讨论】:

    【解决方案5】:
    @echo on
    set var= "%*"
    c:
    cd "C:\Users\MyText Editor"
    start javaw -jar "MyTextEditor.jar"%var%
    pause
    

    成为删除多余的命令

    start "" javaw -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%*"
    pause
    

    Echo 已开启,除非您将其关闭。

    我们不会无缘无故地将东西放入变量中,它已经在%*中。它只是制作复杂的代码并从变量名称中删除含义。

    在编程时(与打字不同),我们不会更改路径(cd /d C:\Users\MyText Editor 确实会驱动器和文件夹)。

    我们在命令行上指定完整路径。这让你的意思很清楚。

    主要问题是 .jar 和 %var% 之间没有空格,并且 start 命令 行中的第一个引号被假定为 CMD 的窗口标题。我会编写 javaw 的路径,而不是使用 start。 Start 是要求 Windows 的图形 shell 启动文件,而不是 CMD。

    这是一个启动 vbs 文件的批处理文件。我没有指定 cscript 的路径,因为它是 Windows 的命令。

    它的复杂性在于让使用相当白痴证明并且对其他人来说很容易。

    @echo off
    
    
    Rem Make sure filter.vbs exists
    set filter=
    set filterpath=
    Call :FindFilter filter.vbs
    
    Rem Add filter.bat to the path if not in there, setx fails if it's already there
    setx path %~dp0;%path% 1>nul 2>nul
    
    
    
    
    Rem Test for some command line parameters
    If not "%1"=="" goto main
    
    echo.
    echo -------------------------------------------------------------------------------
    echo.
    echo   Filter.bat
    
    echo   ==========
    echo.
    echo     The Filter program is a vbs file for searching, replacing, extracting, and 
    echo     trimming console output and text files.
    echo.
    echo     Filter.bat makes Filter.vbs easily usable from the command line. It 
    echo     controls unicode/ansi support and debugging.
    echo.
    echo           Type Filter Help or Filter HTMLHelp for more information.
    echo.
    cscript //nologo "%filter%" menu
    Goto :EOF
    
    :Main
    
    
    echo %date% %time% %~n0 %* >>"%~dp0\FilterHistory.txt"
    
    
    
    rem echo Batch file ran
    rem echo %*
    Rem /ud Unicode and Debug
    If %1==/ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //u //x %%j&Goto :EOF
    
    Rem /u Unicode
    If %1==/u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //u %%j&Goto :EOF
    
    Rem /d Ansi Debug
    If %1==/d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //x %%j&Goto :EOF
    
    Rem -ud Unicode and Debug
    If %1==-ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //u //x %%j&Goto :EOF
    
    Rem /u Unicode
    If %1==-u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //u %%j&Goto :EOF
    
    Rem -d Ansi Debug
    If %1==-d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
    " //nologo //x %%j&Goto :EOF
    
    Rem ANSI
    cscript "%filter%
    " //nologo %*&Goto :EOF
    
    Goto :EOF
    
    :FindFilter
    
    If Exist "%~dpn0.vbs" set filter=%~dpn0.vbs&set filterpath=%~dp0&goto :EOF
    
    echo find filter 1
    If Not "%~dpnx$PATH:1" == "" set filter=%~dpnx1&set filterpath=%~dp1&goto :EOF
    
    echo find filter 2
    If Exist "%temp%\filter.vbs" set filter=%temp%\filter.vbs&set filterpath=%temp%&goto :EOF
    
    copy "%~dpnx0" "%~dpn0.bak"
    if not errorlevel 1 (
        echo creating "%~dpn0.vbs"
        goto :EOF
    )
    
    copy "%~dpnx0" "%temp%\filter.bak" 
    
    echo Error %errorlevel%
    if not errorlevel 1 (
        echo creating "%temp%\filter.bak"
        Goto :EOF
    )
    Goto :EOF
    

    【讨论】:

    • 不,var 的定义中有空格。此外,"%*" 中的引号是问题的实际根源。见my answer
    • c:\Path to Java\JavaW.exe -Jar "C:\Users\MyText Editor\MyTextEditor.jar" "%1" 只需将其放入注册表即可。不需要批处理文件。
    • 是的,在您发表评论前不久,我在编辑的答案中得出了相同的结论。
    猜你喜欢
    • 2021-08-16
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    相关资源
    最近更新 更多