如何使用批处理文件编辑主机文件(检查行,如果不存在则添加,如果存在则删除)?

问题描述:

我有一个批处理脚本,可以在主机文件中添加几行以阻止计算机上的某些网站.

I have a batch script to add several lines to my hosts file to block certain websites on my computer.

我想以这种方式使用批处理脚本,当我运行example.bat时,它首先检查要添加的行是否存在,如果不存在,则不添加它们.但是,如果hosts文件中已经存在该批处理文件,则应删除这些行.换句话说,批处理文件应在hosts文件中切换行的存在.

I would like to use the batch script in such a way that when I run my example.bat, it first checks if the lines to add exist, and if they don't then add them. But the batch file should delete the lines in case of existing already in hosts file. In other words the batch file should toggle the presence of the lines in the hosts file.

这怎么办?

这是我到目前为止所拥有的.它所做的就是添加行.

Here is what I have so far. All it does is adding the lines.

@echo off

:: BatchGotAdmin
::-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SystemRoot%\system32\cacls.exe" "%SystemRoot%\system32\config\system"

REM --> If error flag set, we do not have administrator privileges.
if not errorlevel 1 goto gotAdmin

echo Set UAC = CreateObject^("Shell.Application"^) >"%temp%\getadmin.vbs"
set params=%*
if defined params set params=%params:"=""%
echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B

:gotAdmin
pushd "%CD%"
CD /D "%~dp0"
::--------------------------------------

@echo off

set hostspath=%SystemRoot%\System32\drivers\etc\hosts

echo 127.0.0.1 www.example1.com >> %hostspath%
echo 127.0.0.1 www.example2.com >> %hostspath%
echo 127.0.0.1 www.example3.com >> %hostspath%

exit

带有说明性注释的纯批处理代码:

A pure batch code with explanatory comments:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "hostspath=%SystemRoot%\System32\drivers\etc\hosts"

rem Initialize the array of our hosts to toggle
for %%a in (
    "127.0.0.1 www.example1.com"
    "127.0.0.1 www.example2.com"
    "127.0.0.1 www.example3.com"
) do (
    set /a numhosts+=1
    set "host!numhosts!=%%~a"
)

>"%hostspath%.new" (
    rem Parse the hosts file, skipping the already present hosts from our list.
    rem Blank lines are preserved using findstr trick.
    for /f "delims=: tokens=1*" %%a in ('%SystemRoot%\System32\findstr.exe /n /r /c:".*" "%hostspath%"') do (
        set skipline=
        for /L %%h in (1,1,!numhosts!) do (
            if "%%b"=="!host%%h!" (
                set skipline=true
                set found%%h=true
                echo - %%b 1>&2
            )
        )
        if not "!skipline!"=="true" echo.%%b
    )
    for /L %%h in (1,1,!numhosts!) do (
        if not "!found%%h!"=="true" echo + !host%%h! 1>&2 & echo !host%%h!
    )
)
move /y "%hostspath%" "%hostspath%.bak" >nul || echo Can't backup %hostspath%
move /y "%hostspath%.new" "%hostspath%" >nul || echo Can't update %hostspath%
endlocal
pause