Batch file 批处理文件-主机文件编辑器-防止重复条目-删除以前添加的条目
好的,这是我到目前为止得到的。 这意味着在主机文件中添加要阻止的网站,并允许用户在需要时删除条目。当试图添加网站以阻止时,有时会创建一个新行,然后将条目放在它前面的行上。这不是我想要的。我希望它创建一个新行,然后在该行添加条目。出于某种原因,它有时起作用,有时根本不起作用。我收到一条错误消息,说Find参数不正确。我正在使用Find命令查看条目是否已经在hosts文件中。如果是,我希望它避免添加它。如果不是,那么我想添加它。当我试图删除一个条目时,批处理就崩溃了,所以我不确定我到底做错了什么。我正在尝试查找条目并将其替换为空。我真正想做的是删除整行,这样我就不会有很多空行了。 非常感谢您的帮助。谢谢Batch file 批处理文件-主机文件编辑器-防止重复条目-删除以前添加的条目,batch-file,batch-processing,Batch File,Batch Processing,好的,这是我到目前为止得到的。 这意味着在主机文件中添加要阻止的网站,并允许用户在需要时删除条目。当试图添加网站以阻止时,有时会创建一个新行,然后将条目放在它前面的行上。这不是我想要的。我希望它创建一个新行,然后在该行添加条目。出于某种原因,它有时起作用,有时根本不起作用。我收到一条错误消息,说Find参数不正确。我正在使用Find命令查看条目是否已经在hosts文件中。如果是,我希望它避免添加它。如果不是,那么我想添加它。当我试图删除一个条目时,批处理就崩溃了,所以我不确定我到底做错了什么。我
@echo off
TITLE Modifying your HOSTS file
COLOR F0
:LOOP
cls
SET "CHOICE="
ECHO Choose 1 to block a website
ECHO Choose 2 remove a blocked website
ECHO Choose 3 to exit
SET /P CHOICE= selection %CHOICE%
GOTO %CHOICE%
:1
cls
SET /P WEBSITE=Enter the name of the website to add:
SET HOME= 127.0.0.1
SET NEWLINE=^& echo.
SET BLOCKEDSITE=%HOME% %WEBSITE%
FIND /C /I %BLOCKEDSITE% %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%BLOCKEDSITE%>>%WINDIR%\System32\drivers\etc\hosts
ECHO Website blocked
ping 127.0.0.1 -n 5 > nul
GOTO LOOP
:2
cls
SET /P WEBSITE=Enter the name of the website to remove:
SETLOCAL ENABLEEXTENTIONS DISABLEDELAYEDEXPANSION
SET "HOME= 127.0.0.1 "
SET "BLOCKEDSITE=%HOME% %WEBSITE%"
SET "REPLACE="
SET "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
FOR /F "DELIMS=" %%i IN ('TYPE "%HOSTSFILE%" ^& BREAK ^> "%HOSTSFILE%" ')
DO
(
SET "LINE=%%i"
SETLOCAL ENABLEDELAYEDEXPANSION
>>"%HOSTSFILE%" echo(!LINE:%BLOCKEDSITE%=%REPLACE%!
ENDLOCAL
)
ECHO Website unblocked
GOTO LOOP
:3
EXIT
请注意,当提及
主机
文件的条目时,网站
一词具有误导性。hosts
文件的条目用于DNS主机名到IP地址的自定义映射,文件中存在的任何主机名不一定承载网站。使用术语网站
可能会给人一种错觉,认为类似http://www.example.com
可以添加到主机文件,但该文件不正确
如果主机文件中已存在主机,则跳过该主机:使用
find
的问题在于%BLOCKEDSITE%
中嵌入了空格,因此应将其括起来并使用:FIND /C /I "%BLOCKEDSITE%" %WINDIR%\system32\drivers\etc\hosts
但它还有另一个问题:因为它依赖于IP地址和主机名之间的确切间距,这是%BLOCKEDSITE%
强制要求的,所以它只适用于批处理文件添加的条目。此外,用户可能已通过在包含条目的行中添加#
注释掉(禁用)条目,并且您的批处理代码将跳过添加主机,即使条目被禁用
这可以通过使用findstr
及其正则表达式语法来解决。例如:findstr /IRC:"^ *127\.0\.0\.1 *example\.com *$" "%WINDIR%\system32\drivers\etc\hosts"
从主机文件中删除条目:在
FOR
循环中,您只需跳过写入包含指定条目的行:if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"
findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"
但它同样不准确,并且与前面提到的跳过添加条目的问题相同。再次使用findstr
可以轻松删除包含不需要的条目的行:if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"
findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"
根据上述要点,脚本可以按如下方式重写:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
title Modifying your HOSTS file
color F0
set "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
set "HOME=127.0.0.1"
set "PROMPT_TEXT=Enter the host name to"
set "ACTION_TEXT[1]=add"
set "ACTION_TEXT[2]=remove"
set "FindEmptyLine=^ *$"
set "NewLineAppended="
cls
setlocal EnableDelayedExpansion
:LOOP
echo,
echo 1. Block a host
echo 2. Remove a blocked host
echo 3. Exit
choice /C "123" /N /M "Choose an item [1, 2, 3]: "
set "Item=%errorlevel%"
goto choice%Item%
:choice0 // User Pressed CTRL-C
:choice3
exit /b
:choice1
call :Common
set "HostEntry=!HOME! !HOST!"
findstr /IRC:"!FindEntry!" "!HOSTSFILE!"> nul && (
echo The host !HOST! is already blocked, No action taken.
) || (
if not defined NewLineAppended (
REM This will append a new line ONLY if the file does not end by LF character
type "!HOSTSFILE!" | findstr $ > "!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
set "NewLineAppended=1"
)
)
echo !HostEntry!>>"!HOSTSFILE!"
echo The host !HOST! blocked
)
goto LOOP
:choice2
call :Common
findstr /VIR /C:"!FindEntry!" /C:"!FindEmptyLine!" "!HOSTSFILE!">"!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
echo The host !HOST! unblocked
)
goto LOOP
:Common
set "HOST="
set /P "HOST=!PROMPT_TEXT! !ACTION_TEXT[%Item%]! (e.g. example.com): "
if not defined HOST (
(goto)2>nul
goto LOOP
)
set "FindEntry=^^ *!HOME! *!HOST! *$"
set "FindEntry=!FindEntry:.=\.!"
exit /b
请注意,当提及
主机
文件的条目时,网站
一词具有误导性。hosts
文件的条目用于DNS主机名到IP地址的自定义映射,文件中存在的任何主机名不一定承载网站。使用术语网站
可能会给人一种错觉,认为类似http://www.example.com
可以添加到主机文件,但该文件不正确
如果主机文件中已存在主机,则跳过该主机:使用
find
的问题在于%BLOCKEDSITE%
中嵌入了空格,因此应将其括起来并使用:FIND /C /I "%BLOCKEDSITE%" %WINDIR%\system32\drivers\etc\hosts
但它还有另一个问题:因为它依赖于IP地址和主机名之间的确切间距,这是%BLOCKEDSITE%
强制要求的,所以它只适用于批处理文件添加的条目。此外,用户可能已通过在包含条目的行中添加#
注释掉(禁用)条目,并且您的批处理代码将跳过添加主机,即使条目被禁用
这可以通过使用findstr
及其正则表达式语法来解决。例如:findstr /IRC:"^ *127\.0\.0\.1 *example\.com *$" "%WINDIR%\system32\drivers\etc\hosts"
从主机文件中删除条目:在
FOR
循环中,您只需跳过写入包含指定条目的行:if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"
findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"
但它同样不准确,并且与前面提到的跳过添加条目的问题相同。再次使用findstr
可以轻松删除包含不需要的条目的行:if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"
findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"
根据上述要点,脚本可以按如下方式重写:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
title Modifying your HOSTS file
color F0
set "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
set "HOME=127.0.0.1"
set "PROMPT_TEXT=Enter the host name to"
set "ACTION_TEXT[1]=add"
set "ACTION_TEXT[2]=remove"
set "FindEmptyLine=^ *$"
set "NewLineAppended="
cls
setlocal EnableDelayedExpansion
:LOOP
echo,
echo 1. Block a host
echo 2. Remove a blocked host
echo 3. Exit
choice /C "123" /N /M "Choose an item [1, 2, 3]: "
set "Item=%errorlevel%"
goto choice%Item%
:choice0 // User Pressed CTRL-C
:choice3
exit /b
:choice1
call :Common
set "HostEntry=!HOME! !HOST!"
findstr /IRC:"!FindEntry!" "!HOSTSFILE!"> nul && (
echo The host !HOST! is already blocked, No action taken.
) || (
if not defined NewLineAppended (
REM This will append a new line ONLY if the file does not end by LF character
type "!HOSTSFILE!" | findstr $ > "!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
set "NewLineAppended=1"
)
)
echo !HostEntry!>>"!HOSTSFILE!"
echo The host !HOST! blocked
)
goto LOOP
:choice2
call :Common
findstr /VIR /C:"!FindEntry!" /C:"!FindEmptyLine!" "!HOSTSFILE!">"!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
echo The host !HOST! unblocked
)
goto LOOP
:Common
set "HOST="
set /P "HOST=!PROMPT_TEXT! !ACTION_TEXT[%Item%]! (e.g. example.com): "
if not defined HOST (
(goto)2>nul
goto LOOP
)
set "FindEntry=^^ *!HOME! *!HOST! *$"
set "FindEntry=!FindEntry:.=\.!"
exit /b
那么,哪一行生成了错误消息?请阅读并回答您的问题。在几乎所有文本编辑器中,尤其是接受“正则表达式”术语的编辑器中,使用“查找/替换”功能可以更简单、更直接地执行此过程。我认为没有理由通过使用批处理文件、允许不受控制的最终用户输入和写入临时文件来增加流程的难度或冗长。那么,哪一行生成了错误消息?请阅读并回答您的问题。在几乎所有文本编辑器中,尤其是接受“正则表达式”术语的编辑器中,使用“查找/替换”功能可以更简单、更直接地执行此过程。我认为没有理由通过使用批处理文件、允许不受控制的最终用户输入和写入临时文件来增加流程的难度或冗长。