以冒号作为分隔符的全局/路径名扩展

时间:2010-08-07 13:17:00

标签: bash shell path glob expansion

如何转换包含全局字符的字符串,例如

/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 个答案:

答案 0 :(得分:19)

实际上,我想到了一个更好的解决方案:使用shell函数。

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

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

答案 1 :(得分:10)

这应该适合你:

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

答案 2 :(得分:4)

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

如果你进入Perl,这是非常微不足道的:

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

或Python:

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

或许多其他流行的脚本语言。

答案 5 :(得分:1)

不保存IFS和命令替换

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

答案 6 :(得分:1)

zsh无需弄乱IFS,可以通过一个简单的变量标志连接数组:

dirs=(/var/lib/gems/*/bin(N))
dirs=${(j.:.)dirs}

如果没有文件,第一行的(N)会禁止显示警告; (j.:.):一起加入数组。适用于0、1或多个匹配项。

答案 7 :(得分:0)

另一个oneliner:printf "%s\n" /var/lib/gems/*/bin | paste -s -d':'

但是@ timo的回答在我看来更好。