稳健地构建路径

稳健地构建路径

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

FOLDER_1, FOLDER_2, etc.

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

变量将是:

FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'

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

PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/

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

FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'

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

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

还,我是在重新发明轮子吗? (即是否有任何内置功能可以做到这一点?)。

最后,如果变量位于大批,例如FOLDERS,是否可以在不循环的情况下执行此操作? (或者,通过循环但不知道FOLDERS数组中有多少个)。

答案1

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

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

dir=${(j:/:)FOLDERS}

您可以在执行此操作时压扁重复的斜杠,但这纯粹是装饰性的。

setopt extended_glob
dir=${${(j:/:)FOLDERS}//\/\/##/\/}

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

IFS=/
dir="${FOLDERS[*]}"
unset IFS
dir=${dir//\/+(\/)//}

答案2

您可以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

运算%符修剪尾随字符串,在本例中为/。通过将其应用于parts[@],它会分别修剪每个数组成员。

理解这个技巧的关键printf在于man 1 printf:“格式字符串根据需要经常重用以满足参数。”

答案3

怎么sed不适合你呢?sed 's|/\+|/|g'在连接之后或之前尝试sed 's|/||g'

答案4

bash 4引入了扩展通配符,它​​可以在参数替换中启用正则表达式匹配${var....}...默认情况下关闭。要为您的脚本启用它,只需设置 shell 选项外部全局变量...

假如说$目录==/home/me/////////stuff//items

shopt -s extglob; dir="${dir//+(\/)//}"

结果值$目录

/home/me/stuff/items  

以下是一些有关“做”和“不做”的示例——Bash 扩展通配符

相关内容