"Pretty print" windows% PATH% variable - как разделить на; "; в оболочке CMD
Я хочу запустить простую одностроку в приглашении 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
Ответы
Ответ 1
Простым способом является использование
for %a in ("%path:;=";"%") do @echo %~a
Это работает для всех без ;
в пути и без "
вокруг одного элемента
Протестировано с помощью пути = C:\qt\4.6.3\bin; C:\Program Files; C:\documents & Settings
Но "всегда" решение немного сложнее
EDIT: Теперь рабочий вариант
@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
)
Что я там делал?
Я попытался решить основную проблему: точки с запятой внутри кавычек следует игнорировать, и только нормальные точки с запятой следует заменить на ";"
Я сам использовал пакетный интерпретатор, чтобы решить это для меня.
- Сначала я должен сделать строку безопасной, избегая всех специальных символов.
- Тогда все
;
заменены на ^;^;
- и тогда трюк начинается с линии
set var=%var:"=""%"
(Пропущенная цитата - ключ!).
Это расширяется таким образом, что все экранированные символы теряют свой кадр:
var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;;
...
Но только вне кавычек, так что теперь существует разница между точками с запятой вне кавычек ;;
и внутри ^;^;
,
Это ключ.
Ответ 2
Простой один лайнер для печати типовой переменной PATH
:
ECHO.%PATH:;= & ECHO.%
Если ваш PATH
был равен A;B;C
, приведенная выше замена строки изменит это на ECHO.A & ECHO.B & ECHO.C
и выполнит все за один раз. Полная остановка предотвращает появление сообщений "ECHO on".
Ответ 3
Обновление для Stephan Quan очень умного решения с одним слоем: проблема, с которой я столкнулся, заключалась в том, что конечная полуточка - (и, возможно, два последовательных полуколония, то есть пустой элемент пути), вызовет сообщение "ECHO включено", появиться. Я решил это, вставив период сразу после второго оператора ECHO (который является синтаксисом для подавления сообщений ECHO вкл/выкл). Однако это приведет к дополнительной пустой строке:
ECHO %PATH:;= & ECHO.%
Ответ 4
У меня есть небольшие улучшения для умного "всегда" решения jeb. В настоящее время решение jeb имеет следующие проблемы:
- Если ведущий путь заключен в кавычки, то первый вывод
начинается с ""
- Если конечный путь заключен в кавычки, то последний вывод
заканчивается на ""
- Если какой-либо путь содержит безвредные, но нефункциональные последовательные "",
то выход сохраняет "
- Если var содержит последовательные;; разделители затем выходят ECHO выключен
Это решение устраняет незначительные проблемы, плюс использует 2 замены. Также я устранил ненужное повторное включение/отключение задержки расширения в цикле. (Edit в 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
Различные пустые исправления пути работают и для простого решения jeb.
ОБНОВЛЕНИЕ. Ниже приведен простой простой лайнер с использованием JREPL.BAT
Вы можете использовать мою JREPL.BAT утилиту для регулярного выражения текста, чтобы получить простое, очень надежное решение. JREPL.BAT - это чистый script (гибридный JScript/пакет), который запускается изначально на любом компьютере Windows с XP и далее.
jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path
Ответ 5
Ответ Стивена Куана короче и лучше, но вот решение Python:
python -c "import os; print os.environ['PATH'].replace(';', '\n');"
Превращение ;
с запятой в строки \n
.
Ответ 6
Я знаю, что это старый, но FWIW; Я всегда сталкивался с этим по той или иной причине. Некоторое время назад я написал себе script для этого. Я положил немного польского на него и разместил его в своем блоге.
Не стесняйтесь использовать его.
Он называется epath, и файл находится на inzi.com. Он скомпилирован как EXE для удобства использования (используя vbsedit): здесь
Вы можете скачать exe там. Здесь исходный код для script, если вы хотите его как vbs script.
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
Ответ 7
@ROMANIA_engineer предложил решение PowerShell в комментарии. Поскольку вопрос запрашивает команду, которая работает в оболочке CMD, вот способ использовать этот элегантный код из желаемой среды OP:
powershell -Command ($env:Path).split(';')
Чтобы сделать его еще более читаемым, вы можете добавить сортировку:
powershell -Command ($env:Path).split(';') | sort
Кредит: fooobar.com/questions/28821/...
Ответ 8
Это работает в окне cmd с помощью Git Bash в Windows:
echo -e ${PATH//:/\\n}
Вы также можете сделать удобный псевдоним в своем .bash_profile
:
alias showpath='echo -e ${PATH//:/\\n}'
Ответ 9
Этот скрипт будет анализировать текущий путь 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% 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