0

I want to come up with a command that searches my path variable and outputs the folders that include the search keyword. For example: I want to output all paths included in my path variable that include the word 'python' (case insensitive).

My path looks like this:

C:\Program Files\ConEmu\ConEmu\Scripts;C:\Program Files\ConEmu;C:\Program Files\ConEmu\ConEmu;C:\Program Files\AdoptOpenJDK\jre-11.0.4.11-hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft VS Code\bin;C:\Program Files(x86)\PDFtk\bin\;C:\Program Files\ffmpeg\bin;C:\Program Files\ffmpeg\avconv\bin;C:\Program Files\ffmpeg\curl\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files(x86)\Gpg4win\..\GnuPG\bin;C;C:\Users\jc\AppData\Local\Programs\Python\Python38-32\Scripts\;C:\Users\jc\AppData\Local\Programs\Python\Python38-32\;C:\Users\jc\AppData\Roaming\npm;C:\Program Files\OpenSSH;C:\Users\jc\.ssh;C:\Program Files(x86)\Nmap;C:/Users/jc/AppData/Local/Programs/Python/Python38-32/python.exe;

Expected result would be:

C:\Users\jc\AppData\Local\Programs\Python\Python38-32\Scripts\;C:\Users\jc\AppData\Local\Programs\Python\Python38-32\;C:/Users/jc/AppData/Local/Programs/Python/Python38-32/python.exe;

So far, I have a regex formula that selects every path (see example here). The regex I have is:

C.*?;\gmi

If I try path | findstr "C.*?;"

Nothing really comes out (shouldn't it output all lines that match that regex?). Also, how would I go about outputting the paths that include the intended search keyword? Thanks

jlo
  • 2,157
  • 2
  • 17
  • 23
  • 1
    It is not `grep` and does not support many regex features. See [more about how to use `findstr`](https://stackoverflow.com/questions/8844868/what-are-the-undocumented-features-and-limitations-of-the-windows-findstr-comman). Note you probably want to install `grep` for Windows. Or use Powershell, it is built-in and supports .NET regexps. – Wiktor Stribiżew Apr 08 '21 at 11:36

2 Answers2

2

This will do the needful:

for %A IN ("%PATH:;=" "%") DO @ECHO=%~A | FINd /I "Python"
Ben Personick
  • 3,074
  • 1
  • 22
  • 29
  • Could you explain what the ("%PATH:;=" "%") part does? I understand this is a loop that takes each path, echoes it and filters for 'python', but can't make sense of that part between brackets. Thanks! – jlo Apr 08 '21 at 18:37
  • The solution above will fail if any directory listed in `%PATH%` contains doublequotes, semicolons or ampersands, all of which are perfectly valid in its string entries. – Compo Apr 08 '21 at 18:43
  • @Compo semicolons aren't valid in the path, they will denote separate paths within path, and can;t be used in a directory or file name, extra colons make no difference, other than being completely invalid in a path, so you'll parse these if entered wrongly the same way the OS does, and whether they are valid would make no difference to the task at hand per-se because if they are, then they are also invalid to the OS, and created by fat fingering entries by hand or a poorly written program, and garbage regardless. – Ben Personick Apr 08 '21 at 19:14
  • @Compo The issue of Double quotes might be something we could see someone adding if entering these into the registry by hand, and although I've never in 20 years seen any program actually add a path with double quotes into the path variable, it doesn't mean it couldn't happen so we could certainly add a step and create a temp variable to strip any errant quotes in the path. It might be a tiny chance but it doesn't hurt to add that option. :) – Ben Personick Apr 08 '21 at 19:18
  • Yes they are valid! directories containing them, must be enclosed with doublequotes. In fact, if memory serves, they are the only characters which require their paths to be enclosed with doublequotes. _Those with ampersands and other problematic characters don't need to be_. Have you tried `SET "PATH=%PATH%;"C:\MadeUp\Directory;With;Semicolons\";"` – Compo Apr 08 '21 at 19:19
  • Take a look [here](https://stackoverflow.com/a/8046515) @BenPersonick, for further information which may help. – Compo Apr 08 '21 at 19:28
  • SET "PATH=%PATH%;"C:\MadeUp\Directory;With;Semicolons\";" would only affect the local environment, again, manual setting by hand, and although you "Should" use `Path %Path%;"C:\MadeUp\Directory;With;Semicolons\"` It's a temp change for this local env. either way. So you're right I had forgotten there is a way to get semicolons into a directory name! Neat bit of trivia! If you can find me a program that people have a decent chance of actually having installed which would do that, I'll be shocked, and certainly give you kudos for finding it. – Ben Personick Apr 08 '21 at 19:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/230912/discussion-between-ben-personick-and-compo). – Ben Personick Apr 08 '21 at 19:43
  • 1
    @jlo The `"%PATH:;=" "%"` part is wrapping the variable in outer quotes, and replacing the semicolons (used to separate paths within the paths variable) with a set of double quotes a space and another set of double quotes using CMD's "Variable Substitution". This should effectively wrap all of your paths in double quotes, and allow the default `For` loop to quickly parse them – Ben Personick Apr 08 '21 at 20:32
  • @Compo I already moved this to a chat, chat with me there, Thanks for clarifying. I understood that was the intention, and I acknowledged you were correct in this previously, feel free to continue this in chat if you like. – Ben Personick Apr 08 '21 at 20:51
  • For people still trying to figure out the part in brackets, just run echo "%PATH:;=" "%" and it will print out the result – jlo Apr 09 '21 at 07:46
2

This is not very difficult. The code uses PowerShell to split the Path environment variable, then checks each one for a case insensitive match to the first parameter on the command line.

=== search_path_for.bat

@SET "SEARCH_FOR=%~1"
@powershell -NoLogo -NoProfile -Command ^
    "$Env:Path -split [Io.Path]::PathSeparator |" ^
        "ForEach-Object { if ($_ -match '%SEARCH_FOR%') { $_ } }"

=== Usage

C:>search_path_for.bat "bin"
C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin
C:\Program Files\TortoiseSVN\bin
C:\Program Files\Microsoft VS Code\bin
C:\ProgramData\chocolatey\bin
C:\Users\lit\bin

=== Get a single string result

@SET "SEARCH_FOR=%~1"
@powershell -NoLogo -NoProfile -Command ^
    "($Env:Path -split [Io.Path]::PathSeparator |" ^
        "ForEach-Object { if ($_ -match '%SEARCH_FOR%') { $_ } }) -join [Io.Path]::PathSeparator
lit
  • 14,456
  • 10
  • 65
  • 119