How to split the contents of `$PATH` into distinct

2019-06-22 16:45发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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}'


回答4:

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


回答5:

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


回答6:

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.



标签: bash shell