用一个批次替换另一个批次中的变量输出

用一个批次替换另一个批次中的变量输出

用户在窗口中手动输入存储在变量中的输入数据。然后批处理对包含用户输入数据的变量进行“回显”(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

谢谢

更新:

  1. 我在用放屁并且它已经起作用了:

first.bat

fart.exe second.bat "zuckerberg" "%dbuser%"
fart.exe second.bat "dadada" "%dbpass%"
fart.exe second.bat "mydb" "%dbname%"

但每次替换我都要执行 3 次相同的命令。我想知道是否有其他不依赖外部程序的解决方案(.bat、.cmd)

  1. 另一种解决方案是将“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

但这并不能永久地替换第二个脚本的变量的值(这正是我想要的)。

  1. 另一种解决方案这是 (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

但我无法根据我的兴趣进行调整,因为它重写了输出(不搜索和替换字符串)

  1. 另一种解决方案是与替换器
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

  • 将命令行参数(参数)传递给 Windows 批处理文件

    %~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

相关内容