稳健地构建路径

Ame*_*ina 17 shell-script

假设我在 shell 脚本中有几个变量(例如在 zsh 中):

FOLDER_1, FOLDER_2, etc.
Run Code Online (Sandbox Code Playgroud)

这些变量指的是从/. 例如,如果我有一条路径/home/me/stuff/items

变量将是:

FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'
Run Code Online (Sandbox Code Playgroud)

现在,假设我想通过连接变量来重建相应的路径。一种可能的方法是按如下方式构建路径:

PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/
Run Code Online (Sandbox Code Playgroud)

但是,假设某些变量FOLDER_i带有尾随正斜杠,而其他变量则没有(我们不知道是哪个),例如

FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'
Run Code Online (Sandbox Code Playgroud)

我的问题是:我如何才能稳健地构建路径?(例如避免双斜线,并在需要的地方添加它们)。

我认为一种方法是/在变量对之间添加always ,然后使用 删除任何重复项sed,但我无法使其工作(我不确定我/是否在 中正确处理sed)。

另外,我是在重新发明轮子吗?(即是否有任何内置功能已经做到了这一点?)。

最后,如果变量在一个数组中,例如FOLDERS,是否可以在不循环的情况下做到这一点?(或者,通过循环但不知道FOLDERS数组中有多少)。

Gil*_*il' 18

简单的答案是停止担心并喜欢多个斜线。多个斜杠与单个斜杠具有相同的效果(除了以 开头的路径//在一些系统上具有不同的含义;Windows 上的 unix 仿真层是我唯一能命名的)。这是设计使然,能够组合文件名而不必担心多个斜杠是该设计决策的主要部分。

要连接数组元素,在 zsh 中,可以使用j 参数扩展标志

dir=${(j:/:)FOLDERS}
Run Code Online (Sandbox Code Playgroud)

您可以在使用时挤压重复的斜线,但这纯粹是装饰性的。

setopt extended_glob
dir=${${(j:/:)FOLDERS}//\/\/##/\/}
Run Code Online (Sandbox Code Playgroud)

在 ksh 和 bash 中,您可以使用 的第一个字符$IFS作为分隔符来加入数组。然后,您可以压缩重复的斜杠。在 bash 中,您需要shopt -s extglob在下面代码片段的最后一行启用 ksh glob。

IFS=/
dir="${FOLDERS[*]}"
unset IFS
dir=${dir//\/+(\/)//}
Run Code Online (Sandbox Code Playgroud)


jan*_*sen 13

您可以printf与数组一起使用:

parts=("$FOLDER_1" "$FOLDER_2" "$FOLDER_3");
printf '/%s' "${parts[@]%/}"
# Use "printf -v path" to save it into a variable called "path" instead of printing it
Run Code Online (Sandbox Code Playgroud)

%运营商修剪后的字符串,在这种情况下/。通过将其应用于parts[@],它会分别修剪每个数组成员。

理解这个printf技巧的关键是来自man 1 printf:“格式字符串被尽可能频繁地重用以满足参数。”

  • @fered:在这种情况下,`/*` 不* 表示零个或多个*斜线*,而是斜线后跟任意数量的字符。这意味着如果您的路径以斜杠开头,结果将是空字符串! (2认同)