windows “漂亮打印”窗口 %PATH% 变量 - 如何在“;”上拆分 在 CMD 外壳中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5471556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell
提问by sam
I want to run a simple one-liner in the Windows CMD prompt to print my %PATH%
variable, one entry per line.
我想在 Windows CMD 提示符下运行一个简单的单行来打印我的%PATH%
变量,每行一个条目。
I tried this: for /f "delims=;" %a in ("%path%") do echo %a
but this only prints the first entry:
我试过这个: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\.
Also as you can see from the output above, this is also printing the echo %a
command as well as the output. Is there any way to stop this?
同样从上面的输出中可以看出,这也打印了echo %a
命令和输出。有什么办法可以阻止这种情况吗?
If I try a similar command, I get all the entries, but still get the echo %a
output spamming the results. I don't understand why the following prints all entries, but my attempt on %PATH%
doesn't. I suspect I don't understand the /F
switch.
如果我尝试一个类似的命令,我会得到所有的条目,但仍然会得到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
回答by jeb
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
这适用于所有没有;
在路径中并且没有"
围绕单个元素
测试的路径=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 normalsemicolons 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.
- 首先,我必须使字符串安全,转义所有特殊字符。
- 然后全部
;
替换为^;^;
- 然后技巧从行开始
set var=%var:"=""%"
(缺少的引号是关键!)。
这以某种方式扩展,使得所有转义字符都将丢失其转义插入符:var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;;
...
但仅限于引号之外,因此现在引号之外的分号;;
和内部的分号之间存在差异^;^;
。
这就是关键。
回答by Stephen Quan
A simple one liner to prettying printing the PATH
environment variable:
一个简单的单行打印PATH
环境变量:
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.
如果您PATH
等于A;B;C
上面的字符串替换,则会将其更改为ECHO.A & ECHO.B & ECHO.C
并一次性执行所有操作。句号可防止出现“ECHO 已打开”消息。
回答by user1998693
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:
Stephan Quan 非常聪明的单行解决方案的更新:我遇到的问题是尾随分号 - (可能还有两个连续的分号,即空路径元素)会导致出现消息“ECHO is on”。我通过在第二个 ECHO 语句之后立即插入一个句点来解决这个问题(这是抑制 ECHO 是开/关消息的语法)。但是,它会导致额外的空行:
ECHO %PATH:;= & ECHO.%
回答by dbenham
I have minor improvements to jeb's clever "always" solution. Currently jeb's solution has the following issues:
我对 jeb 巧妙的“始终”解决方案进行了细微的改进。目前jeb的解决方案有以下问题:
- If the leading path is enclosed in quotes, then the first output starts with ""
- If the trailing path is enclosed in quotes, then the last output ends with ""
- If any path contains harmless but non-functional consecutive "", then the output preserves the ""
- If var contains consecutive ;; delimiters then outputs ECHO is off
- 如果前导路径用引号括起来,则第一个输出以“”开头
- 如果尾随路径用引号括起来,则最后的输出以“”结尾
- 如果任何路径包含无害但无功能的连续“”,则输出保留“”
- 如果 var 包含连续的 ;; 分隔符然后输出ECHO 关闭
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)
此解决方案修复了小问题,此外还减少了 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
)
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.
如果您想为连续 ; 产生的每个空路径看到一个空行 分隔符,那么 FOR 循环的最后一行可以简单地读取echo(%%~a
。
Or perhaps it would be more obvious to display empty paths as "" using:if %%a=="" (echo "") else echo %%~a
或者,使用以下方法将空路径显示为 "" 会更明显:if %%a=="" (echo "") else echo %%~a
The various empty path fixes work for jeb's simple solution as well.
各种空路径修复也适用于 jeb 的简单解决方案。
UPDATE: Here is a simple one-liner using JREPL.BAT
更新:这是一个使用 JREPL.BAT 的简单单行
You can use my JREPL.BAT regular expression text processing utilityto 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.BAT 正则表达式文本处理实用程序来实现一个简单、非常健壮的解决方案。JREPL.BAT 是纯脚本(混合 JScript/批处理),可在 XP 以后的任何 Windows 机器上本机运行。
jrepl "([^;\q]+|\q.*?(\q|$))+" python -c "import os; print os.environ['PATH'].replace(';', '\n');"
/x /jmatch /s path
回答by Bob Stein
Stephen Quan's answeris shorter and better, but here's a Python solution:
Stephen Quan 的答案更短更好,但这里有一个 Python 解决方案:
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
Turning ;
semicolons into \n
newlines.
将;
分号变成\n
换行符。
回答by weir
@ROMANIA_engineer proposed a PowerShell solution in a comment. Since the question asks for a command that works in the CMD shell, here is a way to use that elegant code from the OP's desired environment:
@ROMANIA_engineer 在评论中提出了一个 PowerShell 解决方案。由于问题要求在 CMD shell 中工作的命令,这里是一种使用来自 OP 所需环境的优雅代码的方法:
powershell -Command ($env:Path).split(';')
powershell -Command ($env:Path).split(';')
To make it still more readable, you can add sorting:
为了使其更具可读性,您可以添加排序:
powershell -Command ($env:Path).split(';') | sort
powershell -Command ($env:Path).split(';') | sort
回答by Marble68
I know this is old, but FWIW; I always run into wanting this for some reason or another. Some time ago, I wrote myself a script to do this. I put a little polish on it and posted it on my blog.
我知道这很旧,但是 FWIW;由于某种原因,我总是遇到想要这个的情况。前段时间,我自己写了一个脚本来做到这一点。我对其进行了一些润色,然后将其发布到了我的博客上。
Feel free to use it.
随意使用它。
It's called epath, and the file is at inzi.com. It's compiled as an EXE for easy use (using vbsedit): here
它称为 epath,文件位于 inzi.com。它被编译为易于使用的 EXE(使用 vbsedit):here
You can download the exe there. Here's the source code to the script if you want it as a vbs script.
你可以在那里下载exe。如果您希望将其作为 vbs 脚本,这里是该脚本的源代码。
@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|$))+" ##代码## /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
回答by SherylHohman
This works in cmd window using Git Bash on Windows:
这适用于在 Windows 上使用 Git Bash 的 cmd 窗口:
echo -e ${PATH//:/\\n}
echo -e ${PATH//:/\\n}
You can also make a handy alias in your .bash_profile
:
您还可以在您的.bash_profile
:
alias showpath='echo -e ${PATH//:/\\n}'
alias showpath='echo -e ${PATH//:/\\n}'
回答by slyfox1186
This script will parse the current windows path into at txt file using JREPL.bat. It was inspired by the above post by dbenham.
此脚本将使用 JREPL.bat 将当前 Windows 路径解析为 at txt 文件。它的灵感来自 dbenham 的上述帖子。
##代码##