Globbing/pathname expansion with colon as separator

pythonpath multiple directories
add folder to pythonpath
python add all subdirectories to path

How can I convert a string containing glob characters such as

/var/lib/gems/*/bin

into a colon-separated string of filenames (i.e. PATH compatible) matching the pattern?

i.e. echo /var/lib/gems/*/bin will return

/var/lib/gems/1.8/bin /var/lib/gems/1.9.1/bin

I want

/var/lib/gems/1.8/bin:/var/lib/gems/1.9.1/bin 

instead.

The obvious approach is simply to replace the space character with ':' via tr, but that doesn't work if the filename itself contains the space character.

Actually, I thought of a better solution: use a shell function.

function join() {
    local IFS=$1
    shift
    echo "$*"
}

mystring=$(join ':' /var/lib/gems/*/bin)

Globbing/pathname expansion with colon as separator, How can I convert a string containing glob characters such as /var/lib/gems/*/bin. into a colon-separated string of filenames (i.e. PATH compatible) matching the  How can I convert a string containing glob characters such as /var/lib/gems/*/bin into a colon-separated string of filenames (i.e. PATH compatible) matching the pattern?

This should do it for you:

dirs=(/var/lib/gems/*/bin)    # put filenames (dirnames) in an array
saveIFS=$IFS IFS=':'          # set the Internal Field Separator to the desired delimiter
dirs=("${dirs[*]}")           # convert the array to a scalar with the new delimiter
IFS=$saveIFS                  # restore IFS

14 Expansion, How can I convert a string containing glob characters such as /var/lib/gems/*/bin into a colon-separated string of filenames (i.e. PATH compatible) matching the  Normally, when no glob specified matches an existing filename, no pathname expansion is performed, and the globs are not removed: $ echo "Textfiles here:" *.txt Textfiles here: *.txt In this example, no files matched the pattern, so the glob was left intact (a literal asterisk, followed by dot-txt).

PATH="$(printf "%s:" /usr/*/bin)"
PATH="${PATH%:}"

zshexpn(1): zsh expansion/substitution, If the h is followed immediately (with no spaces or other separator) by any number of takes the expansion of *.c and applies the glob qualifiers in the (#q . Repeats the immediately (without a colon) following modifier until the resulting word  Globbing/pathname expansion with colon as separator (8) How can I convert a string containing glob characters such as / var / lib / gems /*/ bin. into a colon-separated string of filenames (i.e. PATH compatible) matching the pattern? i.e. echo /var/lib/gems/*/bin will return

printf "%s\n" /var/lib/gems/*/bin | tr "\n" ":"

Shell Command Language, Filename Generation: This expansion, commonly referred to as globbing, is always done last. Any character can be used as the delimiter in place of '/'. Repeats the immediately (without a colon) following modifier until the resulting word  Globbing/pathname expansion with colon as separator (8) How can I convert a string containing glob characters such as / var / lib / gems /*/ bin. into a colon-separated string of filenames (i.e. PATH compatible) matching the pattern? i.e. echo /var/lib/gems/*/bin will return

It's pretty trivial if you drop into Perl:

perl -e 'print join ":", @ARGV' /var/lib/gems/*/bin

Or Python:

python -c 'import sys; print ":".join(sys.argv[1:])' /var/lib/gems/*/bin

Or any number of other popular scripting languages.

Variables and Expansions, Words that are the concatenation of a name and a colon ( ':' ) are reserved; their It is only field splitting or pathname expansion that can create multiple fields as a delimiter and use the delimiters to split the results of parameter expansion  The good news about globbing in shell is that glob expansion is built into the shell and done after field (IFS) expansion. Thus, as long as you directly use globs as command parameters or as part of a “for” loop, you will have no problem with pathnames containing whitespace or control characters (since they will not undergo field expansion). There is also no challenge getting the

glob - find pathnames matching a pattern, To perform a pathname expansion, we simply write a syntactical glob pattern in the classname :]] When there is a set of colons directly inside the rectangular the separation between bash's arguments and the arguments to your shell code. In this case, the right hand side will be treated as a colon-separated list in the manner of the PATH parameter, so that a `~' or an `=' following a `:' is eligible for expansion. All such behaviour can be disabled by quoting the ` ~ ', the ` = ', or the whole expression (but not simply the colon); the EQUALS option is also respected.

glob, or beginning with a tilde (~), are expanded into The filename component separator character  Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

zsh, Globs. "Glob" is the common name for a set of Bash features that match or expand specific types of patterns. Some synonyms for globbing  the comma separated list is just hard to type, especially when you have tens of runs in some long name. either supporting regex or shell globbing would eliminate the pain. jart mentioned this issue Jun 5, 2018

Comments
  • This works, but I'd use a different variable. You can also do the inital assignment this way: printf -v varname "%s:" /var/lib/gems/*/bin
  • Almost perfect. I think I like piping to sed to remove the trailing colon though ala stackoverflow.com/a/5074995/69002
  • Close! But if there's only one match, you get a colon at the end: "/var/lib/gems/1.9.1/bin:". (And if there's no match, a single colon.)
  • It seems as though this might be the best approach overall (the IFS fiddling is a bit messy), although it is a shame to have have to use an external program...
  • definitely the way to go if you want a one-liner