Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Road to a readable path

by wol (Hermit)
on Apr 15, 2009 at 10:53 UTC ( #757628=CUFP: print w/ replies, xml ) Need Help??

"Hey, Windows, tell me what's on my PATH, but in a more readable way than using the 'path' command."

@perl -e "print \"$_\n\" foreach (grep {$_} split ';', $ENV{path}); "

The above is ready to be saved into a bat file (road.bat?) and saved to a directory somewhere in your path. You can also run it at the command line to find out what your path is :-)

The same principle could be used for Unix-style shells, but I haven't got one to see what changes (if any) would be needed.

--
use JAPH;
print JAPH::asString();

Comment on Road to a readable path
Download Code
Re: Road to a readable path
by JavaFan (Canon) on Apr 15, 2009 at 11:11 UTC
    I guess the equivalent on Unix would be something like:
    perl -E 'say for grep $_, split /:/, $ENV{PATH}'
    However, the grep filters out the empty string. And so does the 2-arg split. But empty strings in PATHs under Unix are significant. So, I'd write:
    perl -E 'say for split /:/, $ENV{PATH}, -1'
Re: Road to a readable path
by jwkrahn (Monsignor) on Apr 15, 2009 at 11:23 UTC

    I don't know if this will work on Windows but it should:

    perl -le "use Env q[@PATH]; print for @PATH"

      It does:

      C:\>perl -MEnv=@PATH -le "print for @PATH" C:\WINDOWS\ ...
        And without the quotes:
        C:\>perl -MEnv=@PATH -le print()for@PATH ...
      Very interesting. I learned two things from that: about the Env module, and using the -l switch to turn print into say. The docs for Env says that $Config::Config{path_sep} is used, so it will handle Windows properly. Looking at the code in Env.pm, I see that split is given two arguments, so trailing nul fields are stripped, which another poster points out is a problem on Unix. Since that is the normal point of using the Env module, perhaps someone should issue a correction? Actually, it will return the nth item as an empty string if asked for, but it will not count it when checking the size, so the loop won't ask for it. It re-splits every time an element is gotten, yuck.
Re: Road to a readable path
by Tanktalus (Canon) on Apr 15, 2009 at 13:05 UTC

    How about:

    perl -MFile::Spec -le 'print for File::Spec->path'
    That should work on Windows, Unix, VMS, and anything else File::Spec supports. :-P

      That should work on Windows...

      Not quite. In one-liners, you have to use double quotes rather than single ones on Windows.

      perl -MFile::Spec -le "print for File::Spec->path"
Re: Road to a readable path
by VinsWorldcom (Priest) on Apr 15, 2009 at 13:37 UTC

    On Windows, you don't even need Perl to get a readable path:

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

    Produces this (for my path):

    {C} > for %i in ("%path:;=" "%") do @echo %i "C:\usr\bin" "C:\Perl\bin" "C:\WINDOWS\system32" "C:\WINDOWS" "C:\WINDOWS\System32\Wbem" "c:\Program Files\Microsoft SQL Server\90\Tools\binn\" "C:\Documents and Settings\Administrator\My Documents\bin" {C} >

    UPDATE: Use "set /?" at the command prompt to find out the new options for environment variable substitution (the %path:;=" "%). Basically, I wrap the %PATH% ENV var in double quotes and then replace all the semicolon separators with a double-quote, space, double quote. This effecitely puts double quotes around all the paths (so spaces won't give any troubles) and we use the for loop to list each newly double-quoted string

      Nor on unix...
      $ echo $PATH | tr ':' '\n'
        echo -e ${PATH//:/\\n}
      On Windows, you don't even need Perl to get a readable path
      Yeah, but you have to do it in a sucky way :p FYI: when you install perl, you also get the "pl2bat" program (it's actually there to support module installation process I believe) to turn your perl programs into *.bat, so that you don't have to write that dumb basic-ish thing to have general purpose commands on you system.
Re: Road to a readable path (unix)
by toolic (Chancellor) on Apr 15, 2009 at 13:45 UTC
    I've had this code for a while, for unix. By default, it prints out PATH, but it can also accept another environment variable name, such as MANPATH or LD_LIBRARY_PATH. The POD explains it all:
    $ perldoc hpath
    =head1 NAME B<hpath> - Human-readable print of Unix PATH variable =head1 SYNOPSIS hpath [name] Options: name Name of an environment variable =head1 DESCRIPTION Prints each item of a path-type environment variable onto its own line +. Useful for displaying PATH variable, for example. A path-type variabl +e is really any variable which is a colon-separated list. Takes as input an environment variable name. Input need not be all upper case. However, the actual variable name m +ust be all upper case. Input need not be the full variable name. However, the abbreviated in +put must allow for "PATH" to be appended to it. For example, "man", "MAN", "manpath" and "MANPATH" will all resolve to "MANPATH". If no input is given, the default is "PATH". Output is STDOUT. =head1 EXAMPLES Print the value of the PATH environment variable, one directory per li +ne: hpath Print the value of the MANPATH environment variable: hpath man Print the value of the LD_LIBRARY_PATH environment variable: hpath LD_LIBRARY_PATH =cut use strict; use warnings; my $name = (@ARGV) ? uc shift : 'PATH'; # If environment variable does not exist, try appending "PATH" to its +name: my $path_var = exists $ENV{$name} ? $ENV{$name} : $ENV{$name . 'PATH'} +; if (defined $path_var) { my @list = split /:/, $path_var; print "$_\n" for @list; }

      That's really neat in that it encourages laziness. The only downside is that so many variables use "_PATH" at the end that it seems silly that I have to type "hpath ld_library_" - it's the underscores that are the painful part to my sense of laziness ;-) So, I have two solutions for you. First is to allow "_PATH" as well as "PATH" as suffixes. The second is to allow "-" as a "lower case" version of "_". The other downside is that limitation on the env vars being uppercase names. So I eliminated that, too (more or less).

      #!/usr/bin/perl =head1 NAME B<hpath> - Human-readable print of Unix PATH variable =head1 SYNOPSIS hpath [name] Options: name Name of an environment variable =head1 DESCRIPTION Prints each item of a path-type environment variable onto its own line +. Useful for displaying PATH variable, for example. A path-type variabl +e is really any variable which is a colon-separated list. Takes as input an environment variable name. Input need not be all upper case. Input need not be the full variable name. However, the abbreviated in +put must allow for "PATH" or "_PATH" to be appended to it. For example, "man", "MAN", "manpath" and "MANPATH" will all resolve to "MANPATH". If no input is given, the default is "PATH". Output is STDOUT. To promote laziness, -'s will be converted to _'s. This allows you to use "ld-library" to print out LD_LIBRARY_PATH. =head1 EXAMPLES Print the value of the PATH environment variable, one directory per li +ne: hpath Print the value of the MANPATH environment variable: hpath man Print the value of the LD_LIBRARY_PATH environment variable: hpath ld-library =cut use strict; use warnings; my $name = (@ARGV) ? uc shift : 'PATH'; # If environment variable does not exist, try appending "PATH" to its +name: my @attempts = ($name, "${name}PATH", "${name}_PATH"); # If that still won't work, try converting -'s to _'s if ($name =~ /-/) { push @attempts, map { (my $n = $_) =~ s/-/_/g; $n } @attempts; } my $path_var; for (@attempts) { if (exists $ENV{$_}) { $path_var = $ENV{$_}; last; } } # if THAT still doesn't work, try case-insensitively. if (not defined $path_var) { for my $a (@attempts) { my @matches = grep { lc $a eq lc } keys %ENV; if (@matches == 1) { $path_var = $ENV{$matches[0]}; last; } elsif (@matches > 1) { # err... which one? Probably should check if one # matches the input exactly, but we'll leave that as # an excersise for the reader :-) last; } } } if (defined $path_var) { my @list = split /:/, $path_var; print "$_\n" for @list; }
      It probably should print "No such env var found" to STDERR if nothing is found, too, but that's a matter of opinion.

      The neat thing here is how much more convenient it is to script something based on the list of directories when they're separated by whitespace, or even newlines, than colons. For example, hpath foo | while read thisfoo; do : stuff ; done Yes, it's possible to do with tr, as above, but with a bunch of smarts in the perl code, you could take a flag from the user for which env var to look at: hpath $1 | while read thisone; do : stuff; done and have the flexibility to allow for shortcuts way easier than pure shell.

        it's the underscores that are the painful part to my sense of laziness ... So, I have two solutions ... second is to allow "-" as a "lower case" version of "_".

        O' indeed. Thanks for caring!

        Tanktalus,

        I found that just replacing the /:/ with /;/ allows this to work under Windoze in a batch file or on the command line!

        Thanks! I dislike Basic...

        ki6jux

        "No trees were harmed in the creation of this node. However, a rather large number of electrons were somewhat inconvenienced."

      The other update to your script didn't add the ,-1 parameter to the end of the split. This is necessary if empty strings are significant.
Re: Road to a readable path
by JavaFan (Canon) on Apr 15, 2009 at 13:51 UTC
    Another way to do it on Unix:
    echo $PATH | perl -F: -lanE 'say for @F'
Re: Road to a readable path
by wol (Hermit) on Apr 21, 2009 at 10:39 UTC
    I had another look at this after all the replies here, and found that perl provides a way to do this without actually using any Perl!
    echo %PATH% | perl -073 -p -l012 -e ""
    Conclusion: When using perl, using Perl is optional...

    --
    use JAPH;
    print JAPH::asString();

Re: Road to a readable path
by John M. Dlugosz (Monsignor) on May 11, 2009 at 20:28 UTC
    I needed something similar for INCLUDE a few days ago. I did it off-the-cuff, and used join instead an explicit loop.

    So, to save it as something reusable, I'd suggest having it take a parameter that is the variable name. Or perhaps the output of another command. Or...maybe the built-in env variable editing command needs to be able to format it nicely.

    —John

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://757628]
Approved by Corion
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2014-07-29 20:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (227 votes), past polls