113

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

/home/user1/MyFolder

现在我想在这个目录中创建 2 个子目录并在那里复制一些文件。

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

我怎样才能做到这一点?

4

7 回答 7

164

POSIX 标准要求在文件名中将多个/视为单个/。因此 //dir///subdir////file与 相同/dir/subdir/file

因此,连接两个字符串以构建完整路径很简单:

full_path="$part1/$part2"
于 2014-06-03T22:31:02.383 回答
44
#!/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 来完成所有这些,-e请在调用中添加一个read

read -e -p "Enter a directory: " BASEPATH
于 2012-06-27T12:40:16.517 回答
20

简单地连接你的路径部分不会完成你想要的吗?

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

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

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

于 2012-06-27T12:38:38.490 回答
5

以下脚本将多个(相对/绝对)路径 (BASEPATH) 与相对路径 (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

shopt -s extglob仅需要允许 BASEPATH 以多个斜杠结束(这可能是无稽之谈)。如果没有扩展的全球范围,您可以使用:

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
于 2017-01-03T22:34:14.657 回答
2

我正在使用我的 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”命令总是会为你修剪终止斜线

于 2019-03-27T09:37:27.373 回答
0
#!/usr/bin/env bash

mvFiles() {
    local -a files=( file1 file2 ... ) \
             subDirs=( subDir1 subDir2 ) \
             subDirs=( "${subDirs[@]/#/$baseDir/}" )

    mkdir -p "${subDirs[@]}" || return 1

    local x
    for x in "${subDirs[@]}"; do
        cp "${files[@]}" "$x"
    done
}



main() {
    local baseDir
    [[ -t 1 ]] && echo 'Enter a path:'
    read -re baseDir
    mvFiles "$baseDir"
}

main "$@"
于 2012-06-27T13:04:32.840 回答
0

这应该适用于空目录(您可能需要检查第二个字符串是否以/应该被视为绝对路径的开头?):

#!/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

参考:Shell 参数扩展

于 2018-07-20T02:48:06.717 回答