如何连接两个字符串以建立一个完整的路径

我在写 bash 脚本。在这个脚本中,我希望用户输入一个目录的路径。然后我想在这个字符串的末尾附加一些字符串,并构建一个到某些子目录的路径。 例如,假设用户输入如下字符串:

/home/user1/MyFolder

Now I want to create 2 subdirectories in this directory and copy some files there.

/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2

我怎么能这么做?

182030 次浏览

难道简单地将你的道路的一部分串联起来不能实现你想要的吗?

$ base="/home/user1/MyFolder/"
$ subdir="subFold1"
$ new_path=$base$subdir
$ echo $new_path
/home/user1/MyFolder/subFold1

然后可以根据需要创建文件夹/目录。

一种惯例是用 /结束目录路径(例如 /home/) ,因为以/开头的路径可能与根目录混淆。如果在路径中使用双斜杠(//) ,它仍然是正确的。但是,如果对任何一个变量都没有使用斜杠,那么它就是不正确的(例如 /home/user1/MyFoldersubFold1)。

#!/bin/bash


read -p "Enter a directory: " BASEPATH


SUBFOLD1=${BASEPATH%%/}/subFold1
SUBFOLD2=${BASEPATH%%/}/subFold2


echo "I will create $SUBFOLD1 and $SUBFOLD2"


# mkdir -p $SUBFOLD1
# mkdir -p $SUBFOLD2

如果你想使用 readline 来完成所有的操作,那么在对 read的调用中添加一个 -e:

read -e -p "Enter a directory: " BASEPATH

POSIX 标准要求将多个 /作为一个文件名中的单个 /处理 //dir///subdir////file is the same as /dir/subdir/file.

因此,将两个字符串连接起来构建一个完整的路径非常简单:

full_path="$part1/$part2"

The following script catenates several (relative/absolute) paths (BASEPATH) with a relative path (SUBDIR):

shopt -s extglob
SUBDIR="subdir"
for BASEPATH in '' / base base/ base// /base /base/ /base//; do
echo "BASEPATH = \"$BASEPATH\" --> ${BASEPATH%%+(/)}${BASEPATH:+/}$SUBDIR"
done

其产出为:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base/subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base/subdir

The shopt -s extglob is only necessary to allow BASEPATH to end on multiple slashes (which is probably nonsense). Without extended globing you can just use:

echo ${BASEPATH%%/}${BASEPATH:+/}$SUBDIR

这将导致不那么整洁但仍然有效的:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base//subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base//subdir

这对于空 dir 应该有效(您可能需要检查第二个字符串是否以 /开始,这应该被视为一个绝对路径?):

#!/bin/bash


join_path() {
echo "${1:+$1/}$2" | sed 's#//#/#g'
}


join_path "" a.bin
join_path "/data" a.bin
join_path "/data/" a.bin

产出:

a.bin
/data/a.bin
/data/a.bin

Reference: 壳参数展开

我正在处理我的 shell 脚本,它需要像你一样做一些路径连接。

问题是,两条路都像

/data/foo/bar


/data/foo/bar/

是有效的。

如果要将文件追加到此路径,则为

/data/foo/bar/myfile

Shell 中没有本机方法(比如 python 中的 os.path.join ())来处理这种情况。

但我发现了一个诀窍

例如,基路径存储在 shell 变量中

BASE=~/mydir

你想加入的最后一个文件名是

FILE=myfile

然后您可以像这样分配您的新路径

NEW_PATH=$(realpath ${BASE})/FILE

然后你会得到

$ echo $NEW_PATH


/path/to/your/home/mydir/myfile

原因很简单,“ realpath”命令总是为您修剪结束斜杠,如果需要的话

最后,我将所有参数 ($*)与’/’(IFS=/- I 内部 F S 分离器)作为分隔符连接起来,然后删除所有重复的’/’(tr -s /)。

我的函数是这样的:

join_paths() {
(IFS=/; echo "'$*'" | tr -s /)
}

@ Dunes 的基本解决方案,但考虑到空弦:

[ -z "$rootpath" ] && rootpath="."
fullpath="${rootpath}/${subdir}"