Глобирование / расширение пути с двоеточием в качестве разделителя
Как я могу преобразовать строку, содержащую символы глобуса, такие как
/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
, но это не работает, если само имя файла содержит символ пробела.
8 ответов
На самом деле, я подумал о лучшем решении: использовать функцию оболочки.
function join() {
local IFS=$1
shift
echo "$*"
}
mystring=$(join ':' /var/lib/gems/*/bin)
Это должно сделать это для вас:
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
Это довольно тривиально, если вы загляните в Perl:
perl -e 'print join ":", @ARGV' /var/lib/gems/*/bin
Или Python:
python -c 'import sys; print ":".join(sys.argv[1:])' /var/lib/gems/*/bin
Или любое количество других популярных языков сценариев.
Не нужно связываться с IFS
, zsh может объединять массивы с простым переменным флагом:
dirs=(/var/lib/gems/*/bin(N))
dirs=${(j.:.)dirs}
(N)
в первой строке подавляется предупреждение, если файлов нет; (j.:.)
присоединяется к массиву с :
s. Работает с 0, 1 или несколькими совпадениями.
Без сохранения IFS и подстановки команд
dirs=(/var/lib/gems/*/bin) ; IFS=: eval 'dirs="${dirs[*]}"'
Еще один вкладчик: printf "%s\n" /var/lib/gems/*/bin | paste -s -d':'
Но на мой взгляд, ответ @timo лучше.