没有延迟扩展的usebackq

usebackq without delayedexpansion

以下从

等远程目录创建 links 的编号列表
1 Link!1
2 Link!2
3 Link!3
4 Link!4
5 Link!5

.

@echo off
setlocal ENABLEDELAYEDEXPANSION

megals --reload /Root/

set /p var1="enter folder name: " & megals /Root/var1

set /a c=0

FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
set /a c=c+1
echo !c! %%i 
set string[!c!]=%%i
)

set /P number=Enter number:
echo !string[%number%]!

pause

第一个问题:所有 link 都包含一个 ! 字符,该字符被延迟扩展删除,使 link 无用。 link 需要 !,因为它是 link.

的一部分

第二个问题:我正在尝试将其集成到一个程序中,但我不能使用 findstr,因为它会列出 link和文件名在同一行,当文件名包含括号时程序崩溃。所以我必须使用 usebackq,因为它让我只得到 link,而不需要处理文件名。

Findstr 将列出 Link!1 Filename(整行)

Usebackq 让我得到 Link!1

我不能用Findstr因为当文件名包含括号时程序会崩溃,只能通过delayedexpansion来解决

这是这里的后续 post,我被卡住了:(显示程序

你可以在那里看到 findstr 方法,以及当文件名包含括号时它是如何导致崩溃的,这可以通过 delayedexpansion 修复,但是删除了 ! 字符,这是必不可少的,因为它是 link.

编辑:现在似乎可以正常工作了,谢谢

工作代码

@echo off

:start:


megals --reload /Root/

set /p var1="dir? " & megals /Root/%%var1%%

for /f "tokens=1,* delims=:" %%A in ('megals -n /Root/%%var1%% ^|findstr
/n "." ') do (
set Link[%%A]=%%B
Echo %%A %%B
)

setlocal DisABLEDELAYEDEXPANSION

set /a c=0

FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
set /a c+=1
call set "string[%%c%%]=%%i"
)

set /P number="Enter number: "

FOR /F "tokens=*" %%g IN ('call echo %%string[%number%]%%') do (SET VAR2=%%g)
echo %Var2%
echo.

Megadl %VAR2% & echo. && goto :start:

pause

https://megatools.megous.com/man/megals.html#_megatools

你真的应该双引号你的整个命令集。
使用备用延迟扩展类型调用:

@echo off
setlocal DisABLEDELAYEDEXPANSION

megals --reload /Root/

set /p var1="enter folder name: " & megals /Root/var1

set /a c=0

FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
    set /a c+=1
    call echo %%c%% %%i 
    call set "string[%%c%%]=%%i"
)

set /P number=Enter number:
call echo %%string[%number%]%%

pause

简单的解决方案是不使用延迟环境变量扩展,例如使用命令 CALL.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

megals.exe --reload /Root/

rem Prompt user for folder name and verify that the user has really entered
rem a folder name and remove double quotes to prevent an exit of batch file
rem execution on further processing because of an invalid command line syntax.

:EnterFolder
set "FolderName="
set /P "FolderName=Enter folder name: "
rem Has the user entered anything at all?
if not defined FolderName goto EnterFolder
rem Remove all double quotes from folder name string?
set "FolderName=%FolderName:"=%"
rem Is anything left from folder name after removing double quotes?
if not defined FolderName goto EnterFolder

megals.exe "/Root/%FolderName%"

rem Get first space/tab separated string of each line output by megals
rem assigned to an environment variable which form an array of strings.
rem Redefine end of line character from semicolon to vertical bar as it
rem is impossible that a line starts with a vertical bar. Command CALL
rem is used to double process the SET command line by Windows command
rem processor which is the alternate solution for delayed expansion.

echo/
set "Count=0"
for /F "eol=|" %%I in ('megals.exe -n -e "/Root/%FolderName%"') do (
    set /A Count+=1
    call echo %%Count%% %%~I
    call set "string[%%Count%%]=%%~I"
)

if %Count% == 0 echo There is nothing! & goto EndBatch
echo/

rem Prompt user for number name and verify that the user has really entered
rem a decimal interpreted number which must be in range of 1-%Count%.

:EnterNumber
set "Number="
set /P "Number=Enter number (1-%Count%): "
rem Has the user entered anything at all?
if not defined Number goto EnterNumber
rem Remove all double quotes from number string?
set "Number=%Number:"=%"
rem Is anything left from number string?
if not defined Number goto EnterNumber
rem Contains the number string any non digit character?
for /F "delims=0123456789" %%I in ("%Number%") do goto EnterNumber

rem Remove all leading zeros from number string to avoid interpreting
rem the entered number as octal number on the two IF comparisons below.

:LeadingZeros
if not %Number:~0,1% == 0 goto CheckNumber
set "Number=%Number:~1%"
if defined Number goto LeadingZeros
rem The number was 0 which is less than 1.
goto EnterNumber

rem Check number in range of 1 to %Count% which requires to convert the
rem number strings on both sides of the comparison operators to signed
rem 32-bit integers by Windows command processor in background.

:CheckNumber
if %Number% GTR %Count% goto EnterNumber
if %Number% LSS 1  goto EnterNumber

rem Output the string according to entered number by forcing Windows command
rem processor again to double processing the command line because of CALL.

call echo %%string[%number%]%%

rem Restore previous environment with discarding all the
rem environment variables defined by this batch file.

:EndBatch
endlocal
pause

另一个解决方案是使用像 OutputAndSet.

这样的子程序
@echo off
setlocal EnableExtensions DisableDelayedExpansion

megals.exe --reload /Root/

rem Prompt user for folder name and verify that the user has really entered
rem a folder name and remove double quotes to prevent an exit of batch file
rem execution on further processing because of an invalid command line syntax.

:EnterFolder
set "FolderName="
set /P "FolderName=Enter folder name: "
rem Has the user entered anything at all?
if not defined FolderName goto EnterFolder
rem Remove all double quotes from folder name string?
set "FolderName=%FolderName:"=%"
rem Is anything left from folder name after removing double quotes?
if not defined FolderName goto EnterFolder

megals.exe "/Root/%FolderName%"

rem Get first space/tab separated string of each line output by megals
rem assigned to an environment variable which form an array of strings.
rem Redefine end of line character from semicolon to vertical bar as it
rem is impossible that a line starts with a vertical bar. Command CALL
rem is used to double process the SET command line by Windows command
rem processor which is the alternate solution for delayed expansion.

echo/
set "Count=0"
for /F "eol=|" %%I in ('megals.exe -n -e "/Root/%FolderName%"') do call :OutputAndSet "%%~I"

if %Count% == 0 echo There is nothing! & goto EndBatch
echo/

rem Prompt user for number name and verify that the user has really entered
rem a decimal interpreted number which must be in range of 1-%Count%.

:EnterNumber
set "Number="
set /P "Number=Enter number (1-%Count%): "
rem Has the user entered anything at all?
if not defined Number goto EnterNumber
rem Remove all double quotes from number string?
set "Number=%Number:"=%"
rem Is anything left from number string?
if not defined Number goto EnterNumber
rem Contains the number string any non digit character?
for /F "delims=0123456789" %%I in ("%Number%") do goto EnterNumber

rem Remove all leading zeros from number string to avoid interpreting
rem the entered number as octal number on the two IF comparisons below.

:LeadingZeros
if not %Number:~0,1% == 0 goto CheckNumber
set "Number=%Number:~1%"
if defined Number goto LeadingZeros
rem The number was 0 which is less than 1.
goto EnterNumber

:OutputAndSet
set /A Count+=1
echo %Count% %~1
set "string[%Count%]=%~1"
goto :EOF

rem Check number in range of 1 to %Count% which requires to convert the
rem number strings on both sides of the comparison operators to signed
rem 32-bit integers by Windows command processor in background.

:CheckNumber
if %Number% GTR %Count% goto EnterNumber
if %Number% LSS 1  goto EnterNumber

rem Output the string according to entered number by forcing Windows command
rem processor again to double processing the command line because of CALL.

call echo %%string[%number%]%%

rem Restore previous environment with discarding all the
rem environment variables defined by this batch file.
:EndBatch
endlocal
pause

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

另请参阅:

  • How does the Windows Command Interpreter (CMD.EXE) parse scripts?