batch - 回显批处理文件中设置的所有变量

时间:2017-01-26 00:19:38

标签: batch-file cmd environment-variables

假设我有这段代码:

@echo off
set "var=value"
echo %var%

现在我的问题是:如何回显文件中的所有变量

我知道你可以这样做:

set

它将显示所有变量。它显示:

ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\foma\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
...

我希望它显示:

var=value

我知道我可以set var显示所有以var开头的变量,但在我的情况下,所有变量都是"导入"从另一个批处理文件,所以我不知道变量名称是如何开始的。 有什么想法吗?

3 个答案:

答案 0 :(得分:7)

@echo off
setlocal
set>originalfile.txt
...
:: list environment changes
set|findstr /x /L /g:originalfile.txt

应该工作 - 快照起始值,然后findstr行应该显示所做的所有更改(删除除外) - 至少在理论上,这只是一个即时的建议。

答案 1 :(得分:3)

将原始cmd环境(保存到文件)与当前环境进行比较。如果需要不同的检查,可以更改文件创建

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem We need a temporary file to store the original environment
    for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (

        rem Retrieve the original environment to the temporary file
        start /i /wait /min "" "%comspec%" /c">""%%~ff"" set "

        rem We need two flag variables. Prepare two names that "should" not collide
        for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (

            rem %%d will be used to determine if we will check for variable deletion 
            rem     on the first inner pass
            rem %%e will be used for matching variables between existing/original variables
            set "%%d="

            rem Retrieve the current environment contents
            for /f "delims= eol==" %%a in ('set') do (

                rem We have not found matching variables
                set "%%e="

                rem Search a match in original set of variables 
                for /f "usebackq delims= eol==" %%o in ("%%~ff") do (

                    rem If variables match, flag it, else check for variable 
                    rem deletion is this is the first loop over the original file
                    if %%a==%%o ( set "%%e=1" ) else if not defined %%d (
                        for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=)
                    )
                )

                rem If no match found, output changed value
                if not defined %%e (echo(%%a)

            rem Now all the variable deletion has been checked.
            ) & if not defined %%d set "%%d=1"

        rem Cleanup flag variables
        ) & set "%%d=" & set "%%e="

    rem Cleanup temporary file
    ) & del "%%~ff"

一旦我们删除了评论

,代码就没那么多了
@echo off
    setlocal enableextensions disabledelayedexpansion
    for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (
        start /i /wait /min "" "%comspec%" /c">""%%~ff"" set "
        for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (
            set "%%d="
            for /f "delims= eol==" %%a in ('set') do (
                set "%%e="
                for /f "usebackq delims= eol==" %%o in ("%%~ff") do (
                    if %%a==%%o ( set "%%e=1" ) else if not defined %%d (
                        for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=)
                    )
                )
                if not defined %%e (echo(%%a)
            ) & if not defined %%d set "%%d=1"
        ) & set "%%d=" & set "%%e="
    ) & del "%%~ff"

已修改仅用于完成。由于dbenham指出前面的代码无法处理名称或值中包含换行符的变量。这是一个可以处理这种情况的混合批处理文件(保存为ex。checkEnvironment.cmd文件)。

@if (@This==@IsBatch) @then /* Batch zone ------------------------------------
@echo off
    setlocal enableextensions disabledelayedexpansion
    call :processCurrentEnvironment "%~f1"
    goto :eof

:processCurrentEnvironment 
    call "%systemroot%\system32\cscript.exe" //nologo //e:JScript "%~f0" /saved:"%~1"
    goto :eof

*/ @end
// Javascript zone -----------------------------------------------------------

var environment = WScript.CreateObject('WScript.Shell').Environment('PROCESS');
var savedFileName = WScript.Arguments.Named.Item('saved');


    if ( !savedFileName ){
        // If no saved file name present, output current environment
        for ( var e = new Enumerator(environment); !e.atEnd(); e.moveNext()){ 
            WScript.StdOut.Write( e.item() + '\0\r\n' );
        };

    } else {
        // Retrieve saved environment to compare against current one
        var savedEnvironment = retrieveSavedEnvironment( savedFileName );

        // For each element in the current environment
        for ( var e = new Enumerator(environment); !e.atEnd(); e.moveNext() ) {

            // retrieve { variable: , value: } representation of the variable 
            var buffer = splitEnvironmentVariable( e.item() );

            if ( buffer ) {
                // if the current variable does not exist in the saved version
                // or if the current value does not match the previous one
                // then dump the current variable
                if (
                    !  savedEnvironment[buffer.variable]
                    || savedEnvironment[buffer.variable].value !== buffer.value
                ) outputVariable( buffer );

                // in any case, this is a processed variable
                delete savedEnvironment[buffer.variable];
            }
        };

        // any saved variables still present are deleted variables, show them
        for (var e in savedEnvironment) outputVariable( e );
    };

// - Helper functions ----------------------------------------------------------

// Process the contents of the saved file to generate a { {variable: , value: }, ... }
// representation of the saved environment

function retrieveSavedEnvironment( savedFileName ) {
    var savedEnvironment = {};
    var buffer = readFile( savedFileName ).split('\0\r\n');
    for (var i in buffer) if ( buffer[i] = splitEnvironmentVariable(buffer[i]) ) {
        savedEnvironment[buffer[i].variable] = buffer[i];
    };
    return ( savedEnvironment );
};

// Read the contents of the saved file - FSO can not be used because we are 
// writing nulls (ascii 0x00 character) to separate variables

function readFile( savedFileName ){
    var buffer = "";
    if (
        WScript.CreateObject('Scripting.FileSystemObject').FileExists( savedFileName )
    ){
        var stream = WScript.CreateObject('ADODB.Stream');
        stream.Open();
        stream.Type = 2
        stream.Charset = 'ascii';
        stream.LoadFromFile( savedFileName );
        buffer = stream.ReadText();
        stream.Close();
    };
    return ( buffer );
};

// Convert variable=value to { variable: , value: }

function splitEnvironmentVariable( text ){
    text = (/^([\s\S][^=]*)=([\s\S]+)/).exec( text ); 
    return (
        text 
        ? { variable : text[1] , value : text[2] } 
        : text
    );
};

// Write the variable with its value or only the variable name 

function outputVariable( variable ){
    if ( typeof variable === 'object' ) {
        WScript.StdOut.WriteLine( variable.variable + '=' + variable.value );
    } else {
        WScript.StdOut.WriteLine( variable + '=' );
    };
};

放置在批处理文件的路径或同一文件夹中,您可以将其用作

@echo off
    setlocal enableextensions enabledelayedexpansion

(SET LF=^
%=this line is empty=%
)

    rem Variables to delete
    set "variableToDelete=1"
    set "my!lf!var1=my!lf!data"

    set "originalEnvironment=%temp%\original_%random%%random%%random%.tmp"

    rem save environment 
    >"%originalEnvironment%" call checkEnvironment.cmd

    rem Create new variable2
    set "thisIsNew=value"
    set "anotherOne=1"

    rem Create another problematic variable
    set "my!lf!var2=my!lf!data"

    rem Delete variables
    set "variableToDelete="
    set "my!lf!var1="

    rem Dump environment changes
    call checkEnvironment.cmd "%originalEnvironment%"

    rem Remove temporary file
    del /q "%originalEnvironment%"

退出
W:\>testEnv.cmd
anotherOne=1
my
var2=my
data
thisIsNew=value
my
var1=
variableToDelete=
W:\>

答案 2 :(得分:0)

无论如何最简单的方法:

@echo off
setlocal enabledelayedexpansion
set "oldfile=oldfile.txt"
set "newfile=newfile.txt"
del %oldfile% >nul 2>nul
del %newfile% >nul 2>nul
for /f %%a in ('set') do echo %%a>>%oldfile%
::---------------------set-vars-here---------------------
set "testone=testonestring"
set "testtow=12324"
::-------------------------------------------------------
for /f %%a in ('set') do echo %%a>>%newfile%
for /f %%a in (%newfile%) do (
find "%%a" %oldfile% >nul 2>nul
if !errorlevel! NEQ 0 (
set "string=%%a"
echo !string!
)
)
del %oldfile% >nul 2>nul
del %newfile% >nul 2>nul
pause