Suppose echo $PATH
yields /first/dir:/second/dir:/third/dir
.
Question: How does one echo the contents of $PATH
one directory at a time as in:
```
$ newcommand $PATH
/first/dir
/second/dir
/third/dir
```
Preferably, I'm trying to figure out how to do this with a for
loop that issues one instance of echo
per instance of a directory in $PATH
.
echo "$PATH" | tr ':' '\n'
Should do the trick. This will simply take the output of echo "$PATH"
and replaces any colon with a newline delimiter.
Note that the quotation marks around $PATH
prevents the collapsing of multiple successive spaces in the output of $PATH
while still outputting the content of the variable.
How about this:
echo "$PATH" | sed -e 's/:/\n/g'
(See sed's s
command; sed -e 'y/:/\n/'
will also work, and is equivalent to the tr ":" "\n"
from some other answers.)
It's preferable not to complicate things unless absolutely necessary: a for loop is not needed here. There are other ways to execute a command for each entry in the list, more in line with the Unix Philosophy:
This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
such as:
echo "$PATH" | sed -e 's/:/\n/g' | xargs -n 1 echo
This is functionally equivalent to a for-loop iterating over the PATH elements, executing that last echo
command for each element. The -n 1
tells xargs
to supply only 1 argument to it's command; without it we would get the same output as echo "$PATH" | sed -e 'y/:/ /'
.
Since this uses xargs
, which has built-in support to split the input, and echoes the input if no command is given, we can write that as:
echo -n "$PATH" | xargs -d ':' -n 1
The -d ':'
tells xargs to use :
to separate it's input rather than a newline, and the -n
tells /bin/echo
to not write a newline, otherwise we end up with a blank trailing line.
My idea is to use echo
and awk
.
echo $PATH | awk 'BEGIN {FS=":"} {for (i=0; i<=NF; i++) print $i}'
EDIT
This command is better than my former idea.
echo "$PATH" | awk 'BEGIN {FS=":"; OFS="\n"} {$1=$1; print $0}'
As an additional option (and in case you need the entries in an array for some other purpose) you can do this with a custom IFS
and read -a
:
IFS=: read -r -a patharr <<<"$PATH"
printf %s\\n "${patharr[@]}"
Or since the question asks for a version with a for loop:
for dir in "${patharr[@]}"; do
echo "$dir"
done
You can use tr
(translate) to replace the colons (:
) with newlines (\n
), and then iterate over that in a for loop.
directories=$(echo $PATH | tr ":" "\n")
for directory in $directories
do
echo $directory
done
If you can guarantee that PATH does not contain embedded spaces, you can:
for dir in ${PATH//:/ }; do
echo $dir
done
If there are embedded spaces, this will fail badly.