批处理列表文件夹内容,然后回显结果作为要设置为变量的选项
Batch list folder contents, then echo results as options to be set as variables
我通常喜欢尝试自己解决这些问题,但现在我不得不承认我不知道从哪里开始。希望有人能至少引导我朝着正确的方向前进。
我有一个包含许多 .txt 文件的文件夹
Text1.txt
Text2.txt
Text3.txt
在我的 windows bat 文件中,我需要列出所述文件夹的内容并将它们设置为要设置为变量的选项。
示例:
cls
echo[
echo[ Please select an option
echo[
echo (1) Text1
echo (2) Text2
echo (3) Text3
echo[
set /p option=Type your selection (1-3) and press ENTER=
if !option!==1 set var=Text1
if !option!==2 set var=Text2
if !option!==3 set var=Text3
非常感谢任何建议,这个论坛很棒。
*编辑
这是我试过的东西
cls
echo[
echo[ Please select an option
echo[
dir /b "*.txt"
echo[
set /p option=Type your selection (1-3) and press ENTER=
if !option!==1 set var=text1
if !option!==2 set var=text2
if !option!==3 set var=text3
它可以工作,但不会在选项前添加数字 (1),而且它们还左对齐而不是居中。
Please select an option
text1.txt
text2.txt
text3.txt
Type your selection (1-3) and press ENTER=
好吧,如果这是任何其他语言,你会怎么做?可能用您的目录列表填充一个数组,对吧?然后使用该数组将菜单选项与文件选择配对?好吧,不要让 Batch 语言没有数组这一事实阻止了您。它们很容易模拟。
@echo off & setlocal
rem // init array index
set file.length=0
rem // for each .txt file in the current directory
for %%I in (*.txt) do (
rem // It's good practice only to enable delayed expansion when needed, as
rem // otherwise it can mangle values containing exclamation marks
setlocal enabledelayedexpansion
rem // use a "for /f" command to endlocal while reading the value of
rem // !file.length!. This preserves exclamation marks in file names.
for /f %%# in ("!file.length!") do endlocal & set "file[%%~#]=%%~I"
rem // set /a doesn't require delayed expansion. It just works.
set /a file.ubound = file.length, file.length += 1
)
rem // Display the collection of variables named file...something.
set file
给你。最后一行应该显示所有以 file
开头的变量的列表,包括模拟的 .length
和 .ubound
属性。从那里,只需使用 for /L %%I in (0, 1, %file.ubound%)
来显示您的菜单。
还有更多内容。首先,我阅读了 解释 txt 文件的数量可以超过 50。默认情况下,Windows cmd 控制台是 24 行。将输出列化以便用户不必滚动不是很好吗?我写了一个实用程序脚本,它将采用一个平面列表并根据当前 cmd 控制台中的行数对其进行列化。将其另存为...
columnify.bat:
@if (@CodeSection == @Batch) @then
@echo off & setlocal
if "%~1"=="test" (
rem // this errors if there's redirected input buffer waiting
timeout /t 0 /nobreak >NUL 2>NUL && (
echo Usage: command list output ^| %~nx0
echo or %~nx0 ^< txtfile containing a list
echo;
echo Hit Ctrl-C to exit.
)
exit
)
for /f "usebackq tokens=1,2 delims=," %%I in (
`powershell "(Get-Host).UI.RawUI.WindowSize.toString()"`
) do (
rem // detect whether input buffer has content waiting
start /b cmd /c "%~f0" test
cscript /nologo /e:JScript "%~f0" %%I %%J
)
goto :EOF
@end // end Batch / begin JScript hybrid code
var stdin = WSH.CreateObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll();
cols = WSH.Arguments(0) * 1 - 1,
rows = WSH.Arguments(1) * 1 - 4;
var out = stdin.split(/\r?\n/), buffer = [], maxlen, col = 0;
if (rows > out.length) { rows = out.length; }
while (out.length) {
buffer[col] = [];
maxlen = 0;
while (buffer[col].length < rows) {
val = out.length ? out.shift() : '';
buffer[col].push(val);
if (maxlen < val.length) maxlen = val.length;
}
for (var i = buffer[col].length; i--;) {
while (buffer[col][i].length < maxlen) { buffer[col][i] += ' '; }
}
col++;
}
for (var i=0; i < buffer[0].length; i++) {
var line = [];
for (var j=0; j < col; j++) {
line.push(buffer[j][i]);
}
WSH.Echo(line.join(' ').substr(0, cols));
}
现在您的主脚本可以通过管道输出来使用 columnify.bat
。
@echo off & setlocal
rem // All the same stuff as above, but without the comments.
set file.length=0
for %%I in (*.txt) do (
setlocal enabledelayedexpansion
for /f %%# in ("!file.length!") do endlocal & set "file[%%~#]=%%~I"
set /a file.ubound = file.length, file.length += 1
)
cls
:displaymenu
echo Always press your luck. Which file do you choose?
echo;
( for /L %%I in (0,1,%file.ubound%) do @(
call echo %%I: %%file[%%~I]%%
) ) | columnify
echo;
set /P "choice=Enter a number: "
if %choice% GEQ 0 if %choice% LEQ %file.ubound% (
setlocal enabledelayedexpansion
echo You chose !file[%choice%]!. Neat.
endlocal
) else (
cls
powershell "write-host -f red 'Invalid response. Enter a number between 0 and %file.ubound%.'"
goto displaymenu
)
您可以构建不同的解决方案,这里有 2 个示例。
如果您只有几个文件可以使用 choice
:
@echo off
setlocal enabledelayedexpansion
for /F "tokens=1,*delims=[]" %%i in ('dir /b /a:-d *.txt ^| find /v /n ""') do (
echo %%i. %%j
set "cnt=!cnt!%%i"
set "fchoice%%i=%%~j"
)
choice /c %cnt% /m "Choose"
echo you chose !fchoice%errorlevel%!
如果你有很多文件,choice
可能不是一个可行的选择,然后恢复到 set /p
:
@echo off
setlocal enabledelayedexpansion
for /F "tokens=1,*delims=[]" %%i in ('dir /b /a:-d *.txt ^| find /v /n ""') do (
echo %%i. %%j
set "cnt=!cnt!%%i"
set "fchoice%%i=%%~j"
set "fin=%%i"
)
set /p "chosen=Select a file by number: "
for /l %%i in (1,1,%fin%) do if "%chosen%" == "%%i" set "check=1"
if not defined check echo Incorrect choice selected & goto :EOF
echo you chose !fchoice%chosen%!
我通常喜欢尝试自己解决这些问题,但现在我不得不承认我不知道从哪里开始。希望有人能至少引导我朝着正确的方向前进。
我有一个包含许多 .txt 文件的文件夹
Text1.txt
Text2.txt
Text3.txt
在我的 windows bat 文件中,我需要列出所述文件夹的内容并将它们设置为要设置为变量的选项。 示例:
cls
echo[
echo[ Please select an option
echo[
echo (1) Text1
echo (2) Text2
echo (3) Text3
echo[
set /p option=Type your selection (1-3) and press ENTER=
if !option!==1 set var=Text1
if !option!==2 set var=Text2
if !option!==3 set var=Text3
非常感谢任何建议,这个论坛很棒。
*编辑 这是我试过的东西
cls
echo[
echo[ Please select an option
echo[
dir /b "*.txt"
echo[
set /p option=Type your selection (1-3) and press ENTER=
if !option!==1 set var=text1
if !option!==2 set var=text2
if !option!==3 set var=text3
它可以工作,但不会在选项前添加数字 (1),而且它们还左对齐而不是居中。
Please select an option
text1.txt
text2.txt
text3.txt
Type your selection (1-3) and press ENTER=
好吧,如果这是任何其他语言,你会怎么做?可能用您的目录列表填充一个数组,对吧?然后使用该数组将菜单选项与文件选择配对?好吧,不要让 Batch 语言没有数组这一事实阻止了您。它们很容易模拟。
@echo off & setlocal
rem // init array index
set file.length=0
rem // for each .txt file in the current directory
for %%I in (*.txt) do (
rem // It's good practice only to enable delayed expansion when needed, as
rem // otherwise it can mangle values containing exclamation marks
setlocal enabledelayedexpansion
rem // use a "for /f" command to endlocal while reading the value of
rem // !file.length!. This preserves exclamation marks in file names.
for /f %%# in ("!file.length!") do endlocal & set "file[%%~#]=%%~I"
rem // set /a doesn't require delayed expansion. It just works.
set /a file.ubound = file.length, file.length += 1
)
rem // Display the collection of variables named file...something.
set file
给你。最后一行应该显示所有以 file
开头的变量的列表,包括模拟的 .length
和 .ubound
属性。从那里,只需使用 for /L %%I in (0, 1, %file.ubound%)
来显示您的菜单。
还有更多内容。首先,我阅读了
columnify.bat:
@if (@CodeSection == @Batch) @then
@echo off & setlocal
if "%~1"=="test" (
rem // this errors if there's redirected input buffer waiting
timeout /t 0 /nobreak >NUL 2>NUL && (
echo Usage: command list output ^| %~nx0
echo or %~nx0 ^< txtfile containing a list
echo;
echo Hit Ctrl-C to exit.
)
exit
)
for /f "usebackq tokens=1,2 delims=," %%I in (
`powershell "(Get-Host).UI.RawUI.WindowSize.toString()"`
) do (
rem // detect whether input buffer has content waiting
start /b cmd /c "%~f0" test
cscript /nologo /e:JScript "%~f0" %%I %%J
)
goto :EOF
@end // end Batch / begin JScript hybrid code
var stdin = WSH.CreateObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll();
cols = WSH.Arguments(0) * 1 - 1,
rows = WSH.Arguments(1) * 1 - 4;
var out = stdin.split(/\r?\n/), buffer = [], maxlen, col = 0;
if (rows > out.length) { rows = out.length; }
while (out.length) {
buffer[col] = [];
maxlen = 0;
while (buffer[col].length < rows) {
val = out.length ? out.shift() : '';
buffer[col].push(val);
if (maxlen < val.length) maxlen = val.length;
}
for (var i = buffer[col].length; i--;) {
while (buffer[col][i].length < maxlen) { buffer[col][i] += ' '; }
}
col++;
}
for (var i=0; i < buffer[0].length; i++) {
var line = [];
for (var j=0; j < col; j++) {
line.push(buffer[j][i]);
}
WSH.Echo(line.join(' ').substr(0, cols));
}
现在您的主脚本可以通过管道输出来使用 columnify.bat
。
@echo off & setlocal
rem // All the same stuff as above, but without the comments.
set file.length=0
for %%I in (*.txt) do (
setlocal enabledelayedexpansion
for /f %%# in ("!file.length!") do endlocal & set "file[%%~#]=%%~I"
set /a file.ubound = file.length, file.length += 1
)
cls
:displaymenu
echo Always press your luck. Which file do you choose?
echo;
( for /L %%I in (0,1,%file.ubound%) do @(
call echo %%I: %%file[%%~I]%%
) ) | columnify
echo;
set /P "choice=Enter a number: "
if %choice% GEQ 0 if %choice% LEQ %file.ubound% (
setlocal enabledelayedexpansion
echo You chose !file[%choice%]!. Neat.
endlocal
) else (
cls
powershell "write-host -f red 'Invalid response. Enter a number between 0 and %file.ubound%.'"
goto displaymenu
)
您可以构建不同的解决方案,这里有 2 个示例。
如果您只有几个文件可以使用 choice
:
@echo off
setlocal enabledelayedexpansion
for /F "tokens=1,*delims=[]" %%i in ('dir /b /a:-d *.txt ^| find /v /n ""') do (
echo %%i. %%j
set "cnt=!cnt!%%i"
set "fchoice%%i=%%~j"
)
choice /c %cnt% /m "Choose"
echo you chose !fchoice%errorlevel%!
如果你有很多文件,choice
可能不是一个可行的选择,然后恢复到 set /p
:
@echo off
setlocal enabledelayedexpansion
for /F "tokens=1,*delims=[]" %%i in ('dir /b /a:-d *.txt ^| find /v /n ""') do (
echo %%i. %%j
set "cnt=!cnt!%%i"
set "fchoice%%i=%%~j"
set "fin=%%i"
)
set /p "chosen=Select a file by number: "
for /l %%i in (1,1,%fin%) do if "%chosen%" == "%%i" set "check=1"
if not defined check echo Incorrect choice selected & goto :EOF
echo you chose !fchoice%chosen%!