Переменная 'Pretty print' windows% PATH% - как разделить на ';'в оболочке CMD - PullRequest
45 голосов
/ 29 марта 2011

Я хочу запустить простую однострочную строку в командной строке Windows CMD, чтобы напечатать мою переменную %PATH%, по одной записи в строке.

Я пробовал это: for /f "delims=;" %a in ("%path%") do echo %a, но это печатает только первую запись:

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

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

Кроме того, как видно из вышеприведенного вывода, здесь также выводятся команда echo %a и вывод. Есть ли способ остановить это?

Если я попробую подобную команду, я получу все записи, но все равно получу вывод echo %a со спамом. Я не понимаю, почему следующее печатает все записи, но моя попытка %PATH% не делает. Я подозреваю, что не понимаю переключатель /F.

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

Z:\>echo 1
1

Z:\>echo 2
2

Z:\>echo 3
3

Ответы [ 9 ]

68 голосов
/ 29 марта 2011

Простой способ - использовать

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

Это работает для всех без ; в пути и без " вокруг одного элемента
Проверено с путем = C: \ qt \4.6.3 \ bin; C: \ Program Files; C: \ documents & Settings

Но решение "всегда" немного сложнее
РЕДАКТИРОВАТЬ: теперь рабочий вариант

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

Что я там делал?
Я пытался решить главную проблему: точки с запятой внутри кавычек следует игнорировать, и только нормальные точки с запятой следует заменить на";"

Я использовал сам пакетный интерпретатор, чтобы решить это для меня.

  • Сначала я должен сделать строку safe , избегая всех специальных символов.
  • Затем все ; заменяются на ^;^;
  • , а затем трюк начинается со строки
    set var=%var:"=""%" (пропущенная кавычка - ключ!).
    Это расширяется таким образом, что все экранированные символы теряют свою escape-карету:
    var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;; ...
    Но только за пределами кавычек , поэтому теперь существует разница между точками с запятой внецитаты ;; и внутри ^;^;.
    Вот ключ.
64 голосов
/ 29 апреля 2014

Простая однострочная печать переменной среды PATH:

ECHO.%PATH:;= & ECHO.%

Если ваш PATH был равен A;B;C, то приведенная выше подстановка строк изменит это на ECHO.A & ECHO.B & ECHO.C и выполнит все это за один раз. Полная остановка предотвращает появление сообщений «ECHO on».

10 голосов
/ 11 июня 2014

Обновление очень умного однострочного решения Стефана Куана: проблема, с которой я столкнулся, заключалась в том, что конечная точка с запятой - (и, возможно, две последовательные точки с запятой, то есть пустой элемент пути) вызвала бы сообщение «ECHO включено»появляться.Я решил эту проблему, вставив точку сразу после второго оператора ECHO (это синтаксис для подавления сообщений ECHO on / off).Однако это приведет к дополнительной пустой строке:

ECHO %PATH:;= & ECHO.%
8 голосов
/ 29 октября 2011

У меня есть небольшие улучшения в умном «всегда» решении Джеба. В настоящее время решение Джеба имеет следующие проблемы:

  1. Если начальный путь заключен в кавычки, то первый вывод начинается с ""
  2. Если конечный путь заключен в кавычки, то последний вывод заканчивается на ""
  3. Если какой-либо путь содержит безвредные, но нефункциональные последовательные "", тогда на выходе сохраняется ""
  4. Если переменная содержит последовательный ;; разделители затем выводит ECHO выключен

Это решение устраняет незначительные проблемы, а также использует на 2 замены меньше. Также я устранил ненужное повторное включение / отключение отложенного расширения внутри цикла. (Изменить на 2011-10-30 упрощенная логика ENDLOCAL)

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

Если вы хотите видеть пустую строку для каждого пустого пути, следующего из последовательных ;; разделители, тогда последняя строка цикла FOR может просто читать echo(%%~a.

Или, возможно, было бы более очевидно отобразить пустые пути как "", используя:
if %%a=="" (echo "") else echo %%~a

Различные исправления пустых путей работают и для простого решения Джеба.


ОБНОВЛЕНИЕ: Вот простой однострочный текст, использующий JREPL.BAT

Вы можете использовать мою утилиту обработки текста с регулярными выражениями JREPL.BAT , чтобы получить простое, очень надежное решение. JREPL.BAT - это чистый скрипт (гибридный JScript / batch), который работает на любом компьютере под управлением Windows начиная с XP.

jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path
2 голосов
/ 02 мая 2015

Ответ Стивена Куана короче и лучше, но вот решение Python:

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

Превращение ; точек с запятой в \n новых строк.

1 голос
/ 31 августа 2017

@ ROMANIA_engineer предложил решение PowerShell в комментарии.Поскольку вопрос требует команду, которая работает в оболочке CMD, вот способ использовать этот элегантный код из требуемой среды OP:

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

Чтобы сделать его еще более читабельнымВы можете добавить сортировку:

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

Кредит: https://stackoverflow.com/a/34920014/704808

1 голос
/ 12 сентября 2013

Я знаю, что это старый, но FWIW;Я всегда сталкиваюсь с желанием этого по той или иной причине.Некоторое время назад я написал для этого сценарий.Я добавил немного блеска и разместил его в своем блоге.

Не стесняйтесь его использовать.

Это называется epath, и файл находится на inzi.com.Для удобства использования он скомпилирован как EXE-файл (с помощью vbsedit): здесь

Вы можете скачать exe там.Вот исходный код скрипта, если вы хотите использовать его как скрипт vbs.

    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
0 голосов
/ 13 мая 2019

Этот скрипт будет анализировать текущий путь Windows в TXT-файле, используя JREPL.bat.Это было вдохновлено вышеупомянутым сообщением dbenham.

@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 голосов
/ 04 июля 2018

Это работает в окне cmd с использованием Git Bash в Windows:

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

Вы также можете создать удобный псевдоним в вашем .bash_profile:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...