Created
December 15, 2025 14:27
-
-
Save tnhung2011/206b1a85dea6e181a09b6d35a5312300 to your computer and use it in GitHub Desktop.
Aggregates local hosts files to the global one, rejecting any duplicates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @echo off | |
| :: detect wrapping | |
| :: writePublic defined = jump to :writePublic | |
| :: this evades CTRL-C canceling all operations | |
| :: https://stackoverflow.com/a/27131024 | |
| if "%~1"=="" if defined writePublic (goto writePublic) else (goto noargs) | |
| set writePublic= | |
| setlocal enableextensions enabledelayedexpansion | |
| if "%~1"=="/?" goto help | |
| set "hosts=%SystemRoot%\System32\drivers\etc\hosts" | |
| set "args=%*" | |
| set "args.proc=%args:*/d:=%" | |
| if "%args.proc%"=="%args%" goto checkNoc | |
| for /f "tokens=1" %%d in ("%args.proc%") do ( | |
| set "args=!args:/d:%%d=!" | |
| echo:>>"%%~d" && set hosts="%%~d" || ( | |
| 1>&2 echo ERROR: Unable to create file: %%d | |
| exit /b 1 | |
| ) | |
| ) | |
| :checkNoc | |
| set "args=%args:/noc%=%" | |
| set "args.proc=%args:/noc=%" | |
| :: for/f strips leading whitespaces | |
| ::set args.proc | |
| for /f "tokens=* delims=]" %%a in ("]%args.proc%") do if ""=="%%a" ( | |
| :noargs | |
| 1>&2 echo ERROR: Insufficient arguments | |
| exit /b 1 | |
| ) | |
| set ignoreComments= | |
| if not "%args%"=="%args.proc%" set ignoreComments=1 | |
| set "args=%args.proc%" | |
| :: does not update timestamp | |
| for %%f in (%hosts%) do ( | |
| echo DESTINATION: %%~f | |
| ren %%f "%%~nxf" || ( | |
| 1>&2 echo ERROR: File locked or insufficient credentials (i.e. not admin^). | |
| exit /b 1 | |
| ) | |
| ) | |
| :: detect cr/lf at end of file | |
| :: https://www.dostips.com/forum/viewtopic.php?f=3&t=11311#p70156 | |
| findStr /v $ %hosts% >nul && echo:>>%hosts% | |
| :: /noc specified | |
| if defined ignoreComments ( | |
| set hosts.temp="%temp%\hosts" | |
| >!hosts.temp! findstr /rc:"^[^#]" %hosts% | |
| set writePublic=1 | |
| rem wrap | |
| cmd /c "%~f0" | |
| rem deletion failure won't affect errorlevel | |
| del !hosts.temp! | |
| 1>&2 echo Successfully deleted !hosts.temp! | |
| exit /b 0 | |
| ) | |
| :: fall through | |
| :: /noc not specified | |
| set hosts.temp=%hosts% | |
| :writePublic | |
| for %%f in (%args%) do ( | |
| echo SOURCE: %%~f | |
| for /f "useback tokens=1,2 eol=#" %%a in ("%%~f") do ( | |
| >nul find /c /i "%%b" %hosts.temp% && ( | |
| echo [EXISTS] %%b | |
| ) || ( | |
| echo [%%a] %%b | |
| echo:%%a %%b>>%hosts% | |
| ) | |
| )) | |
| exit /b 0 | |
| :help | |
| echo Aggregates HOSTS files, writing any entry with nonmatching hostnames | |
| echo to the destination | |
| echo: | |
| echo HOSTS [/noc] sources [/d:destination] | |
| echo: | |
| for /f %%A in ('prompt $H ^&echo on ^&for %%B in ^(1^) do rem') do set bs=%%A | |
| echo %bs% sources Specifies the HOSTS file(s) to be aggregated. Wildcards can be used. | |
| echo %bs% /d:destination Specifies the destination HOSTS file. | |
| echo %bs% (default: %%SystemRoot%%\System32\drivers\etc\hosts) | |
| echo %bs% /noc Ignore comments when matching against the destination. | |
| echo %bs% If the console window is closed while specifying /noc (not Ctrl+C), | |
| echo %bs% you should clean up this temporary file: "%%temp%%\hosts" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment