wake-up-neo.net

'Pretty print' Windows-Variable% PATH% - Aufteilung nach ';' in der CMD-Shell

Ich möchte einen einfachen Einzeiler in der Windows CMD-Eingabeaufforderung ausführen, um meine %PATH%-Variable zu drucken, einen Eintrag pro Zeile.

Ich habe folgendes versucht: for /f "delims=;" %a in ("%path%") do echo %a, aber dies gibt nur den ersten Eintrag aus:

Z:\>for /f "delims=;" %a in ("%path%") do echo %a

Z:\>echo c:\python25\.
c:\python25\.

Wie Sie der obigen Ausgabe entnehmen können, wird auch der Befehl echo %a sowie die Ausgabe gedruckt. Gibt es eine Möglichkeit, dies zu stoppen?

Wenn ich einen ähnlichen Befehl ausprobiere, bekomme ich alle Einträge, bekomme aber trotzdem die echo %a-Ausgabe, die die Ergebnisse spammt. Ich verstehe nicht, warum das Folgende alle Einträge druckt, aber mein Versuch mit %PATH% nicht. Ich vermute, ich verstehe den /F-Schalter nicht.

Z:\>for %a in (1 2 3) do echo %a

Z:\>echo 1
1

Z:\>echo 2
2

Z:\>echo 3
3
42
sam

Der einfache Weg ist zu benutzen

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

Dies funktioniert für alle ohne ; im Pfad und ohne " um ein einzelnes Element
Getestet mit Pfad = C:\qt\4.6.3\bin; C:\Programme; C:\Dokumente & Einstellungen

Eine "immer" Lösung ist jedoch etwas kompliziert
EDIT: Jetzt eine Arbeitsvariante  

@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
)

Was habe ich dort gemacht?
Ich habe versucht, das Hauptproblem zu lösen: Die Semikola innerhalb von Anführungszeichen sollten ignoriert werden, und nur die normalen - Semikola sollten durch ";" 

Ich habe den Batch-Interpreter selbst verwendet, um das für mich zu lösen. 

  • Zuerst muss ich die Zeichenfolge safe machen, um alle Sonderzeichen zu umgehen. 
  • Dann werden alle ; durch ^;^; ersetzt. 
  • und dann beginnt der Trick mit der Linie
    set var=%var:"=""%" (Das fehlende Zitat ist der Schlüssel!).
    Dies erweitert sich so, dass alle entflohenen Charaktere ihren Fluchtpfeil verlieren:
    var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;;...
    Aber nur außerhalb der Anführungszeichen, gibt es jetzt einen Unterschied zwischen Semikolons außerhalb von Anführungszeichen ;; und innerhalb von ^;^;.
    Das ist der Schlüssel.
64
jeb

Ein einfacher Liner, um die Umgebungsvariable PATH zu drucken:

ECHO.%PATH:;= & ECHO.%

Wenn Ihre PATH gleich A;B;C war, ändert die obige Zeichenkettenersetzung dies in ECHO.A & ECHO.B & ECHO.C und führt alles auf einmal aus. Der Punkt verhindert, dass die Meldungen "ECHO ist eingeschaltet" angezeigt werden.

62
Stephen Quan

Ein Update zu Stephan Quans sehr cleverer Einzeilerlösung: Das Problem, dem ich begegnete, war, dass ein nachfolgendes Semikolon (und möglicherweise zwei aufeinanderfolgende Semikolons, d. H. Ein leeres Pfadelement) die Meldung "ECHO ist eingeschaltet" verursachen würde. Ich löste dies, indem ich einen Punkt unmittelbar nach der zweiten ECHO-Anweisung einfügte (dies ist die Syntax zur Unterdrückung von ECHO-Ein/Aus-Meldungen). Es wird jedoch eine zusätzliche leere Zeile erhalten:

ECHO %PATH:;= & ECHO.%
10
user1998693

Ich habe kleinere Verbesserungen an der cleveren "immer" -Lösung von jeb. Derzeit hat die Lösung von jeb die folgenden Probleme:

  1. Wenn der führende Pfad in Anführungszeichen steht, beginnt die erste Ausgabe mit "".
  2. Wenn der nachfolgende Pfad in Anführungszeichen eingeschlossen ist, endet die letzte Ausgabe mit "".
  3. Wenn ein Pfad harmlose, aber nicht funktionierende aufeinanderfolgende "" Pfade enthält, behält die Ausgabe die "" bei.
  4. Wenn var aufeinanderfolgende enthält ;; Begrenzer geben dann aus ECHO ist aus

Diese Lösung behebt die kleineren Probleme und benötigt 2 Substitutionen weniger. Außerdem habe ich die unnötige wiederholte Aktivierung/Deaktivierung der verzögerten Erweiterung innerhalb der Schleife beseitigt. (Edit am 30.10.2011 vereinfachte die ENDLOCAL-Logik)

@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
)

Wenn Sie eine leere Zeile für jeden leeren Pfad sehen möchten, der sich aus aufeinander folgenden ergibt ;; Trennzeichen, dann kann die letzte Zeile der FOR-Schleife stattdessen einfach echo(%%~a lesen.

Oder vielleicht ist es offensichtlicher, leere Pfade als "" anzuzeigen, indem man verwendet:
if %%a=="" (echo "") else echo %%~a

Die verschiedenen Korrekturen für leere Pfade funktionieren auch für die einfache Lösung von jeb.


UPDATE: Hier ist ein einfacher Einzeiler mit JREPL.BAT

Sie können mein JREPL.BAT-Textverarbeitungsprogramm für reguläre Ausdrücke verwenden, um eine einfache, sehr robuste Lösung zu erhalten. JREPL.BAT ist ein reines Skript (Hybrid-JScript/Batch), das nativ auf jedem Windows-Computer ab XP) ausgeführt wird.

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

Ich weiß, das ist alt, aber FWIW; Ich habe immer das Bedürfnis, dies aus irgendeinem Grund zu wollen. Vor einiger Zeit schrieb ich mir ein Skript, um dies zu tun. Ich habe etwas poliert und in meinem Blog veröffentlicht.

Fühlen Sie sich frei, es zu benutzen.

Es heißt epath und die Datei befindet sich auf inzi.com. Es ist als EXE für die einfache Verwendung (mit vbsedit) kompiliert: hier

Sie können das Exe dort herunterladen. Hier ist der Quellcode für das Skript, wenn Sie es als VBS-Skript verwenden möchten.

    scriptname = Wscript.ScriptName 'objFSO.GetFileName(WScript.FullName)

    Function BubbleSort(arrData,strSort)
    'borrowed from here: http://vbscripter.blogspot.com/2008/03/q-how-do-i-sort-data-in-array.html

    'Input: arrData = Array of data.  Text or numbers.
    'Input: strSort = Sort direction (ASC or ascending or DESC for descending)
    'Output: Array
    'Notes: Text comparison is CASE SENSITIVE
    '        strSort is checked for a match to ASC or DESC or else it defaults to Asc


        strSort = Trim(UCase(strSort))
        If Not strSort = "ASC" And Not strSort = "DESC" Then
            strSort = "ASC"
        End If 

        For i = LBound(arrData) to UBound(arrData)
          For j = LBound(arrData) to UBound(arrData)
            If j <> UBound(arrData) Then
                If strSort = "ASC" Then
                  If UCase(arrData(j)) > UCase(arrData(j + 1)) Then
                     TempValue = arrData(j + 1)
                     arrData(j + 1) = arrData(j)
                     arrData(j) = TempValue
                  End If
                End If

                If strSort = "DESC" Then
                    If UCase(arrData(j)) < UCase(arrData(j + 1)) Then
                        TempValue = arrData(j + 1)
                        arrData(j + 1) = arrData(j)
                        arrData(j) = TempValue
                     End If        
                End If 
            End If
          Next
        Next

        BubbleSort = arrData

    End Function

    If Wscript.Arguments.Count>0 Then

        Set args = Wscript.Arguments

        bInLines = False
        bInAlphabetical = False
        bReverseSort = False
        bShowHelp = False

        For Each arg In args
            Select Case arg
                Case "-l"
                    bInLines = True
                Case "-a"
                    bInAlphabetical = True
                Case "-r"
                    bReverseSort = True
                Case Else
                    bShowHelp=True
            End Select  

        Next

        If bInLines = False Then
            bShowHelp=True
        End if

        If bShowHelp Then

                    sTxt = sTxt + "" & vbCrLf
                    sTxt = sTxt +  scriptname  & " Displays the system path in optionally friendly formats." & vbCrLf
                    sTxt = sTxt +  "ePath is helpful when viewing the system path and easily identifying folders therein." & vbCrLf
                    sTxt = sTxt + "" & vbCrLf
                    sTxt = sTxt + "EPATH [-l] [-a] [-r]" & vbCrLf
                    sTxt = sTxt + "" & vbCrLf
                    sTxt = sTxt + "Switches:" & vbCrLf
                    sTxt = sTxt + vbTab + "[-l]" + vbtab + "Show the path broken out in lines" & vbCrLf
                    sTxt = sTxt + vbtab + "[-a]" + vbTab + "Sort the path broken out in lines sorted alphabetically" & vbCrLf
                    sTxt = sTxt + vbtab + "[-r]" + vbTab + "Reverse the alphabetic sort [asc default] (ignored without -a)" & vbCrLf
                    sTxt = sTxt + "" & vbCrLf
                    sTxt = sTxt + vbTab + "Examples:" & vbCrLf
                    sTxt = sTxt +  vbTab + vbTab + scriptname  & vbTab & "(Show %PATH% normally)" & vbCrLf
                    sTxt = sTxt +  vbTab + vbTab + scriptname  & " -l" & vbCrLf
                    sTxt = sTxt +  vbTab + vbTab + scriptname  & " -l -a" & vbCrLf
                    sTxt = sTxt +  vbTab + vbTab + scriptname  & " -l -a -r" & vbCrLf
                    sTxt = sTxt +  vbTab + vbTab + scriptname  & " -? Display help (what you are seeing now)" & vbCrLf
                    sTxt = sTxt + "" & vbCrLf
                    sTxt = sTxt + "More info or questions at http://inzi.com" & vbCrLf


                    Wscript.Echo sTxt

                    WScript.Quit

        Else
            Set wshShell = CreateObject( "WScript.Shell" )
            sPath = wshShell.ExpandEnvironmentStrings( "%PATH%" )
            thePath = Split(sPath,";")

            If bInAlphabetical Then
                If bReverseSort Then
                    sDirection = "DESC"
                End If

                thePath = BubbleSort(thePath, sDirection)
            End if


            For Each item In thePath
                WScript.Echo item
            Next
            Set wshShell = Nothing
        End if
    Else
        'Nothing, echo the path.

        Set wshShell = CreateObject( "WScript.Shell" )
        WScript.Echo wshShell.ExpandEnvironmentStrings( "%PATH%" )
        Set wshShell = Nothing

    End If
1
Marble68

Stephen Quans Antwort ist kürzer und besser, aber hier ist eine Python-Lösung:

python -c "import os; print os.environ['PATH'].replace(';', '\n');"

;-Semikolons in \n-Zeilenumbrüche umwandeln.

1
Bob Stein

@ROMANIA_engineer schlug in einem Kommentar eine PowerShell-Lösung vor. Da in der Frage nach einem Befehl gefragt wird, der in der CMD-Shell funktioniert, können Sie diesen eleganten Code aus der gewünschten Umgebung des OP verwenden:

powershell -Command ($env:Path).split(';')

Um es noch besser lesbar zu machen, können Sie eine Sortierung hinzufügen:

powershell -Command ($env:Path).split(';') | sort

Gutschrift: https://stackoverflow.com/a/34920014/704808

1
weir

Dieses Skript analysiert den aktuellen Windows-Pfad mithilfe von JREPL.bat in eine TXT-Datei. Es wurde von dem obigen Beitrag von dbenham inspiriert.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

:::: THIS SCRIPT WILL PARSE THE CURRENT WINDOWS PATH INTO AT TXT FILE ::::
:::: EACH FOLDER FOUND IN PATH WILL BE ON A SEPARATE LINE ::::

:::: SCRIPT INSTRUCTIONS ::::
:: PLACE JREPL.bat IN C:\WINDOWS\SYSTEM32 FOLDER OR CUSTOM LOCATION OF YOUR CHOOSING ::
:: IF PLACED IN CUSTOM FOLDER YOU MUST LINK IT TO WINDOWS PATH ::
:: YOU CAN ACCESS WINDOWS PATH BY RUNNING THE BELOW COMMAND IN CMD.EXE ::
:: Rundll32 sysdm.cpl,EditEnvironmentVariables ::
:: DOWNLOAD JREPL.bat https://www.dostips.com/forum/viewtopic.php?t=6044 ::

:: SET WORKING DIRECTORY ::
CD /D "C:\WINDOWS\SYSTEM32"

:: UNCOMMENT LINE BELOW AND SET YOUR JREPL.bat SAVED FOLDER PATH IF YOU HAVE A BACKUP COPY ::
:: SET JOUT=<FOLDER PATH>

:: SET OUTPUT FILE ::
    SET FOUT=%USERPROFILE%\DESKTOP\PARSE.TXT

:: SET FILE TO SEARCH FOR ::
:: THIS SEARCHES FOR JREPL.BAT IN THE CURRENT WORKING DIR ::
    SET I=JREPL.BAT

:: SET CONTROL FILE TO CHECK AGAINST ::
:: THIS IS FOR DEBUGGING PURPOSES AND SHOULD NOT BE CHANGED OTHERWISE ::
    SET J=JREPL.BAT

:::: START SCRIPT ::::
    SET RESULT=
    FOR /F "DELIMS=" %%A IN ('DIR /B /O:N ^| FINDSTR /S /I "%I%" %TMP_RESULT_FILE%') DO (
    SET RESULT=%%A
    )

IF /I !RESULT! EQU %J% (
ECHO !RESULT! ^^!^^!EXISTS^^!^^!
    TIMEOUT 3 >NUL
    CALL :FOUND
    GOTO END
) ELSE (
    GOTO NOTFOUND
)
    GOTO ERROR

:FOUND
    FOR %%G IN (%I%) DO (
    %%G "([^;\Q]+|\Q.*?(\Q|$))+" $0 /X /JMATCH /S PATH>>%FOUT%
    CLS && ECHO.
ECHO %I% ^^!^^!EXECUTED SUCCESSFULLY^^!^^!
    TIMEOUT /T 3 >NUL
    Explorer "%FOUT%"
    GOTO END
( ELSE )
    GOTO ERROR
)

:NOTFOUND
    ECHO %I% ^^!^^!NOT FOUND^^!^^!
    TIMEOUT 3 >NUL
    CLS && ECHO.
:: UNCOMMENT THE LINES BELOW TO OPEN JREPL.BAT SAVE FOLDER IF AVAILABLE ::
    :: ECHO ^^!^^!OPENING^^!^^! %I%'S SAVED FOLDER
  :: TIMEOUT 3 >NUL
    :: Explorer "%JOUT%"
  GOTO END
    ( ELSE )
    GOTO ERROR
    )

:ERROR
    CLS && ECHO.
    ECHO ^^!^^!ERROR RUNNING^^!^^! %I%
    TIMEOUT 3 >NUL
    CLS && ECHO.
    ECHO ^^!^^!PLEASE FIX SCRIPT^^!^^! ::::::::::::::::::
    TIMEOUT 3 >NUL

:END
    ENDLOCAL && EXIT /B
0
slyfox1186

Dies funktioniert im cmd-Fenster unter Verwendung von Git Bash unter Windows:

echo -e ${PATH//:/\\n} 

Sie können auch einen praktischen Alias ​​in Ihrem .bash_profile eingeben:

alias showpath='echo -e ${PATH//:/\\n}'

0
SherylHohman