22

如何转换包含 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 

反而。

显而易见的方法是简单地用 ':' via 替换空格字符tr,但如果文件名本身包含空格字符,那将不起作用。

4

8 回答 8

20

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

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

mystring=$(join ':' /var/lib/gems/*/bin)
于 2010-08-08T21:41:38.517 回答
12

这应该为你做:

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
于 2010-08-07T13:39:21.130 回答
6
PATH="$(printf "%s:" /usr/*/bin)"
PATH="${PATH%:}"
于 2010-08-07T15:07:02.813 回答
4

不用IFS纠结,zsh 可以用一个简单的变量标志来连接数组:

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

(N)如果没有文件,第一行的 会抑制警告;与s(j.:.)连接数组。:适用于 0、1 或多个匹配项。

于 2019-01-02T19:04:00.720 回答
2
printf "%s\n" /var/lib/gems/*/bin | tr "\n" ":"
于 2010-08-07T13:28:52.853 回答
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

或任何数量的其他流行脚本语言。

于 2010-08-07T21:11:36.427 回答
2

不保存 IFS 和命令替换

dirs=(/var/lib/gems/*/bin) ; IFS=: eval 'dirs="${dirs[*]}"'
于 2018-12-11T16:56:25.973 回答
0

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

但我认为@timo 的回答更好。

于 2017-09-22T13:28:13.610 回答