windows - usebackq uden forsinket udvidelse

Indlæg af Hanne Mølgaard Plasc

Problem



Følgende opretter en nummereret liste over links fra en ekstern bibliotek som


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


Første problem : Alle links indeholder et ! tegn, der fjernes ved delayedexpansion, hvilket gør linket ubrugeligt. Linkene kræver ! som det er en del af linket.


Andet problem : Jeg forsøger at integrere dette i et program, og jeg kan ikke bruge findstr fordi det vil liste linket og filnavnet på samme linje, og når filnavnet indeholder parenteser programmet kolliderer. Så jeg skal bruge usebackq fordi det lader mig få linket, uden at skulle håndtere filnavnet.


Findstr vil liste Link!1 Filename (hele linjen)


Usebackq lader mig bare få Link!1


Jeg kan ikke bruge Findstr, fordi når filnavne indeholder parenteser, vil programmet kollidere, hvilket kun kan løses ved delayedexpansion.


Dette er en opfølgningspost herfra, som jeg fik fast på: ( Viser programmet )

https://stackoverflow.com/questions/49564553/create-a-numbered-list-based-on-a-given-list-of-strings#=


Du kan se findstr-metoden der, og hvordan det forårsager nedbrud, når filnavne indeholder parenteser, som kan fastsættes med delayedexpansion, men det fjerner karakteren !, hvilket er vigtigt, da det er en del af linket.


Rediger: Synes at arbejde nu, tak


Arbejdskode


@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[28]

Bedste reference


Du bør virkelig dobbeltkaste alle dine sæt kommandoer.

Brug af alternativet forsinket ekspansionstype med et opkald:


@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

Andre referencer 1


Den enkle løsning bruger ikke forsinket miljøvariabel ekspansion, for eksempel ved at bruge kommandoen 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


En anden løsning bruger en subrutine som 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


For at forstå de anvendte kommandoer og hvordan de virker, skal du åbne et kommandopromptvindue, udføre de følgende kommandoer, og læs helt alle hjælpesider, der vises for hver kommando, meget omhyggeligt.



  • call /?

  • echo /?

  • endlocal /?

  • for /?

  • goto /?

  • if /?

  • pause /?

  • rem /?

  • set /?

  • setlocal /?



Se også:



  • Hvordan analyserer Windows Command Interpreter (CMD.EXE) scripts?

  • Symbol svarende til NEQ, LSS, GTR, etc. i Windows-batch-filer

  • Sådan indstilles miljøvariabler med mellemrum?

  • Hvor vender GOTO: EOF tilbage til?