用户在窗口中手动输入存储在变量中的输入数据。然后批处理对包含用户输入数据的变量进行“回显”(first.bat):
set source=%HOMEDRIVE%\test\data.txt
mydialogbox=%HOMEDRIVE%\test\myprogram_dialogbox.exe
SetLocal EnableDelayedExpansion
:: dialog box
for /f "tokens=1-3 delims=" %%i in ('%mydialogbox% --forms --title="Dialog" --text="Set Data" --add-entry="USER" --add-entry="PASSWORD" --add-entry="DBNAME" --separator=","') do (
set line=%%i
echo(!line: =!> %source%
)
IF EXIST %source% (GOTO setdata) else (GOTO end)
:setdata
FOR /F "eol=; tokens=1-3 delims=," %%A IN (%source%) DO (
set dbuser=%%A
set dbpass=%%B
set dbname=%%C
)
echo your imput: %dbuser% %dbpass% %dbname%
例如:
your input: mydb zuckerberg dadada
%dbuser%
%dbpass%
%dbname%
所以我需要在另一个脚本(second.bat)中替换这些变量的值:
set dbname=foo
set dbuser=bar
set dbpass=blabla
预期输出(变化不能是动态的,而是永久的):
set dbname=mydb
set dbuser=zuckerberg
set dbpass=dadada
我该怎么做呢?
PS: 在 Linux 上这很容易
sed -e "s:$dbuser:zuckerberg:g" second.bat
PS:如果我要求的不起作用,那么有没有办法使用%dbuser%
%dbpass%
%dbname%
变量的first.bat
输出second.bat
谢谢
更新:
- 我在用放屁并且它已经起作用了:
first.bat
:
fart.exe second.bat "zuckerberg" "%dbuser%"
fart.exe second.bat "dadada" "%dbpass%"
fart.exe second.bat "mydb" "%dbname%"
但每次替换我都要执行 3 次相同的命令。我想知道是否有其他不依赖外部程序的解决方案(.bat、.cmd)
- 另一种解决方案是将“echo”的输出放在变量中
second.bat
:
first.bat
:
echo your imput: %dbuser% %dbpass% %dbname%
second.bat
:
FOR /F "tokens=*" %%g IN ('echo %dbuser%') do (SET myuser=%%g)
etc
但这并不能永久地替换第二个脚本的变量的值(这正是我想要的)。
- 另一种解决方案这是 (
first.bat
):
(for /f "tokens=1* delims=:" %%a in (%source%) do (
if "%%b"=="" (echo %%a) else (
echo %%a|find " id" >null&& echo %%a: ||echo %%a: %%b
)
))>second.bat
但我无法根据我的兴趣进行调整,因为它重写了输出(不搜索和替换字符串)
call replacer.bat "second.bat" "zuckerberg" "%dbuser%"
它和 fart-it 有同样的问题。每次替换时我都必须运行一个命令(这对我的代码来说不是很优化),并且依赖于外部脚本。
答案1
在执行时传入经典批处理脚本 cmd 参数second.bat
应该没有问题。使用此方法完全消除了更改任何内容的需要second.bat
。
它本质上是second.bat
动态的,并使用传入的参数参数作为变量,这些变量包含传入参数值(例如)的占位符值(例如%~1
,等) 。%~2
"flockingbird" "clockingmerge" "wishyword"
第二个.bat
SET "dbuser=%~1"
FOR /F "tokens=*" %%g IN ('echo %dbuser%') do (SET "myuser=%%~g")
etc
执行
您可以选择最适合执行或调用second.bat
脚本的方法,无论是使用call
、、start
类似方法second.bat "flockingbird"
还是其他任何可以在执行时传递参数值的方法second.bat
另一个例子
批
@echo off
set "dbname=%~1"
set "dbuser=%~2"
set "dbpass=%~3"
echo %dbname%
echo %dbuser%
echo %dbpass%
pause
执行
C:\Folder\second.bat "flockingbird" "clockingmerge" "wishyword"
输出
flockingbird
clockingmerge
wishyword
支持资源
-
批处理文件只能处理
%0
以下参数%9
%0
是被调用的程序名,%1
是第一个命令行参数,%2
是第二个命令行参数,依此类推,直到%9
。 -
%~1
展开 %1 删除任何周围的引号(“) -
CALL
第二个批处理文件该
CALL
命令将启动一个新的批处理文件上下文以及任何指定的参数。当到达第二个批处理文件的末尾时(或如果EXIT
使用),控制将返回到初始CALL
语句之后。参数可以作为简单字符串或使用变量传递:
CALL MyScript.cmd "1234"
CALL OtherScript.cmd %_MyVariable%
答案2
您可以使用call
函数来传递变量。
%source%
在您的代码中,我将在file.txt
此处引用。
文件.txt内容:
really,big,rabbit
测试1脚本内容:
FOR /F "eol=; tokens=1-3 delims=," %%A IN (file.txt) DO (
set dbuser=%%A
set dbpass=%%B
set dbname=%%C
)
call test2.bat
测试2内容:
@echo OFF
echo db user is %dbuser%
echo db pass is %dbpass%
echo the dbname is %dbname%
现在如果你test1.bat
在 cmd 中运行,你会得到以下输出:
db user is really
db pass is big
the dbname is rabbit
test2.bat 是您可以放置需要作为第二批处理运行的变量的地方,以便使用这些参数执行某些操作。
答案3
您不能在 CMD 会话之间共享局部变量。
您需要使用一个全局机制使得它们可以从另一个会话访问,例如一个公共文件、注册表或系统变量(参见命令setx
)。
答案4
以下是处理首次运行初始化所涉及的逻辑的示例。强烈建议对作为参数传递的用户输入数据进行额外验证。
@Echo off
Set "var1="
Set "var2="
Set "var3="
Rem if file called with 3 arguments
If not "%~3" == "" (
If not exist "%TEMP%\%~n0_firstrun.dat" (
<nul set /p "=Initiallizing... "
Rem assumes delayed expansion state is disabled
Set "var1=%~1"
Set "var2=%~2"
Set "var3=%~3"
>"%TEMP%\%~n0_firstrun.dat" (
Setlocal EnableDelayedExpansion
Echo Set "var1=!var1!"
Echo Set "var2=!var2!"
Echo Set "var3=!var3!"
Endlocal
Rem optional - use conditional operator to flag write permission / filename error to calling script
) || (
Echo Failed - Permission or Filename error
exit /b 1
)
Rem Optional - guard initialization file from accidental user deletion
REM Attrib +R "%TEMP%\%~n0_firstrun.dat"
echo - Initiallization Complete
)
) Else If not exist "%TEMP%\%~n0_firstrun.dat" If not "%~1" == "" If "%~3" == "" (
Echo Initiallization Failed - Insufficient arguments provided
Exit /B 2
)
cls
Rem attempt to load the variables.
Rem flags error in the event user has deleted the initialization file
(For /f "UsebackQ delims=" %%G in ("%TEMP%\%~n0_firstrun.dat")Do %%G) || (
Rem user has deleted the initialization file
Exit /b 2
)
Set Var
Pause