'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

The simple way is to use

for %a in ("%path:;=";"%") do @echo %~a

This works for all without ; in the path and without " around a single element
Tested with path=C:\qt\4.6.3\bin;C:\Program Files;C:\documents & Settings

But a "always" solution is a bit complicated
EDIT: Now a working variant

@echo off
setlocal DisableDelayedExpansion
set "var=foo & bar;baz<>gak;"semi;colons;^&embedded";foo again!;throw (in) some (parentheses);"unmatched ;-)";(too"

set "var=%var:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"

set "var=%var:;=^;^;%"
rem ** This is the key line, the missing quote is intended
set var=%var:""="%
set "var=%var:"=""%"

set "var=%var:;;="";""%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
set "var=%var:"=""%"
set "var=%var:"";""=";"%"
set "var=%var:"""="%"

setlocal EnableDelayedExpansion
for %%a in ("!var!") do (
    endlocal
    echo %%~a
    setlocal EnableDelayedExpansion
)

What did I do there?
I tried to solve the main problem: that the semicolons inside of quotes should be ignored, and only the normal semicolons should be replaced with ";"

I used the batch interpreter itself to solve this for me.

  • First I have to make the string safe, escaping all special characters.
  • Then all ; are replaced with ^;^;
  • and then the trick begins with the line
    set var=%var:"=""%" (The missing quote is the key!).
    This expands in a way such that all escaped characters will lose their escape caret:
    var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;;...
    But only outside of the quotes, so now there is a difference between semicolons outside of quotes ;; and inside ^;^;.
    Thats the key.

A simple one liner to prettying printing the PATH environment variable:

ECHO.%PATH:;= & ECHO.%

If your PATH was equal to A;B;C the above string substitution will change this to ECHO.A & ECHO.B & ECHO.C and execute it all in one go. The full stop prevents the "ECHO is on" messages from appearing.


An update to Stephan Quan's very clever one-liner solution: The problem I encountered was that a trailing semi-colon - (and maybe two successive semi-colons, i.e. empty path element) would cause the message "ECHO is on" to appear. I solved this by inserting a period immediately after the second ECHO statement (which is the syntax to suppress ECHO is on/off messages). However, it will result in an extra empty line:

ECHO %PATH:;= & ECHO.%

I have minor improvements to jeb's clever "always" solution. Currently jeb's solution has the following issues:

  1. If the leading path is enclosed in quotes, then the first output starts with ""
  2. If the trailing path is enclosed in quotes, then the last output ends with ""
  3. If any path contains harmless but non-functional consecutive "", then the output preserves the ""
  4. If var contains consecutive ;; delimiters then outputs ECHO is off

This solution fixes the minor issues, plus it uses 2 fewer substitutions. Also I eliminated the unnecessary repeated enabling/disabling delayed expansion within the loop. (Edit on 2011-10-30 simplified the ENDLOCAL logic)

@echo off
setlocal DisableDelayedExpansion
set "var=%var:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
for %%a in ("!var:"S"S=";"!") do (
  if "!!"=="" endlocal
  if %%a neq "" echo %%~a
)

If you want to see a blank line for each empty path resulting from consecutive ;; delimiters, then the last line of the FOR loop can simply read echo(%%~a instead.

Or perhaps it would be more obvious to display empty paths as "" using:
if %%a=="" (echo "") else echo %%~a

The various empty path fixes work for jeb's simple solution as well.


UPDATE: Here is a simple one-liner using JREPL.BAT

You can use my JREPL.BAT regular expression text processing utility to achieve a simple, very robust solution. JREPL.BAT is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward.

jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path