8

I've placed my PATH in a text file and would like to print each path on a newline using a simple command in UNIX.

I've found a long way to do it that goes like this...

cat Path.txt | awk -F\; '{print $1"\n", $2"\n", ... }'

This however seems inefficient so I know there must be a way to quickly print out my results on new lines each time without having to manually call each field separated by the delimiter.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Nick
  • 487
  • 1
  • 4
  • 21

6 Answers6

17

Yet another way:

echo $PATH | tr : '\n'

or:

tr : '\n' <Path.txt
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • Since I've been ragging on other people for bashisms, I feel like I have to point out that some systems ship a `tr` that doesn't understand `'\n'`. '' works, though. – zwol Oct 23 '12 at 23:55
  • In case anyone else wonders: PATH entries are not allowed to contain colons. Ie. there's no escape mechanism: http://stackoverflow.com/a/29213487/1517969 – olejorgenb Aug 06 '16 at 10:59
2

The tr solution is the right one but if you were going to use awk then there'd be no need for a loop:

$ echo "$PATH"
/usr/local/bin:/usr/bin:/cygdrive/c/winnt/system32:/cygdrive/c/winnt

$ echo "$PATH" | awk -F: -v OFS="\n" '$1=$1'
/usr/local/bin
/usr/bin
/cygdrive/c/winnt/system32
/cygdrive/c/winnt
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • Just to mention gawk and mawk have native windows binary, work well with cmd.exe, cheers! – MeaCulpa Oct 24 '12 at 05:02
  • what does the OFS mean in the above comment? – Nick Oct 29 '12 at 22:59
  • It's the Output Field Separator. I'm telling awk to take a list fields separated by colons (FS = input Field Separator) and print them separated by newlines (OFS = Output Field Separator) instead. – Ed Morton Oct 29 '12 at 23:18
0

With Perl for UNIX/UNIX-likes :

echo $PATH | perl -F: -ane '{print join "\n", @F}'

With any OSes (tested on Windows XP, Linux, Minix, Solaris):

my $sep;
my $path;

if ($^O =~ /^MS/) {
    $sep = ";";
    $path = "Path";
}
else {
     $sep = ":";
     $path = "PATH";
}

print join "\n", split $sep, $ENV{$path} . "\n";

If using for Unix, try the following code :

printf '%s\n' ${PATH//:/ }

This use bash parameter expansion

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • The only virtue of shell is its extreme portability. If you can't do something in shell using only the facilities that existed in Unix98, you are better off switching to a real programming language than making use of unportable shell extensions. – zwol Oct 23 '12 at 23:47
  • @Zack, if you need portability, stop using shell, and take a try to python, ruby or perl. – Gilles Quénot Oct 23 '12 at 23:58
  • But that's exactly my point! The moment you need an unportable shell feature is the moment to stop using shell! – zwol Oct 24 '12 at 00:01
  • Added another one Perl solution. – Gilles Quénot Oct 24 '12 at 00:04
0

I have a Perl script that I use for this:

#!/usr/bin/env perl
#
#   "@(#)$Id: echopath.pl,v 1.8 2011/08/22 22:15:53 jleffler Exp $"
#
#   Print the components of a PATH variable one per line.
#   If there are no colons in the arguments, assume that they are
#   the names of environment variables.

use strict;
use warnings;

@ARGV = $ENV{PATH} unless @ARGV;

foreach my $arg (@ARGV)
{
    my $var = $arg;
    $var = $ENV{$arg} if $arg =~ /^[A-Za-z_][A-Za-z_0-9]*$/;
    $var = $arg unless $var;
    my @lst = split /:/, $var;
    foreach my $val (@lst)
    {
        print "$val\n";
    }
}

I invoke it like:

echopath $PATH
echopath PATH
echopath LD_LIBRARY_PATH
echopath CDPATH
echopath MANPATH
echopath $CLASSPATH

etc. You can specify the variable name, or the value of the variable; it works both ways.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

awk:

echo $PATH|awk -F: '{gsub(/:/,"\n");print}'

perl:

echo $PATH|perl -F: -lane 'foreach(@F){print $_}'
Vijay
  • 65,327
  • 90
  • 227
  • 319
0

for AWK, in addition to:

echo $PATH | awk -vFS=':' -vOFS='\n' '$1=$1'

You can:

echo $PATH | awk -vRS=':' '1'
MeaCulpa
  • 881
  • 1
  • 6
  • 14