批处理 %1 获取带有空格的路径

Batch %1 get path with whitespace

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

示例:

opening file "C:\Users\Desktop\space true.txt"

%1 gives:"C:\Users\Desktop\space" and then %2 gives: "true.txt"

我怎么能只得到带有名称和白色 space 的完整文件路径而不尝试通过组合 %1%2%3%4 来尝试获取完整路径的循环...

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

抱歉,沟通有误。下面的代码正在运行。诀窍是用“%*”代替“%1”

这里是代码:

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

我把整个路径都改了,因为我双击的文件和批处理文件在不同的目录下。我不得不把它改成这个。

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

最适合我的解决方案来自这位优秀的绅士 dbenham。

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

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

提前致谢

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

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

埃里克

%*

这是字符列表。

&    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.
@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% 之间没有 space 和 start 命令 第一个引号该行假定为 CMD 的 window 标题。我会编写 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

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

这一行是您问题的根源:

set var= "%*"

将文件拖到批处理脚本中,或者双击文本文件时,任何包含 space 的文件名都会自动用引号引起来。

当您添加自己的附加引号时,它违背了引号的目的 - space 不再被引号。

例如,像 "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

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

编辑 - 以下应该有效

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

我通过命令行测试了关联更改。这必须通过具有管理员权限的提升命令提示符来完成。在我的机器上,我转到“开始”菜单,单击 "All Programs",单击 "Accessories" 文件夹,右键单击 "Command Prompt",然后单击 select "Run as administrator",然后单击 "Yes" 允许程序对系统进行更改。

以下命令将显示需要修改的文件类型

assoc .txt

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

我相信以下内容对您有用:

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

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

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

您的批处理脚本如下所示,无论以何种方式调用它都应该有效(拖放文件名包含 & 但不包含 space 除外):

@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"

你的问题确实是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