Расширение Globbing/pathname с помощью двоеточия в качестве разделителя

Как преобразовать строку, содержащую символы glob, такие как

/var/lib/gems/*/bin

в разделенную двоеточием строку имен файлов (то есть совместимую с PATH), соответствующую шаблону?

то есть. echo /var/lib/gems/*/bin вернет

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

Я хочу

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

вместо.

Очевидный подход - просто заменить символ пробела на ":" на tr, но это не сработает, если само имя файла содержит пробельный символ.

Ответы

Ответ 1

Собственно, я думал о лучшем решении: используйте функцию оболочки.

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

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

Ответ 2

Это должно сделать это за вас:

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

Ответ 3

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

Ответ 4

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

Ответ 5

Это довольно тривиально, если вы заглянете в Perl:

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

Или Python:

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

Или любое количество других популярных языков сценариев.

Ответ 6

Еще один oneliner: printf "%s\n" /var/lib/gems/*/bin | paste -s -d':'

Но @timo ответ лучше, на мой взгляд.

Ответ 7

без сохранения IFS и подстановки команд

dirs=(/var/lib/gems/*/bin) ; IFS=: eval 'dirs="${dirs[*]}"'