我正在尝试编写一个 bash 脚本。在此脚本中,我希望用户输入目录的路径。然后我想在这个字符串的末尾附加一些字符串并建立一个到一些子目录的路径。例如假设用户输入这样的字符串:
/home/user1/MyFolder
现在我想在这个目录中创建 2 个子目录并在那里复制一些文件。
/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2
我怎样才能做到这一点?
POSIX 标准要求在文件名中将多个/
视为单个/
。因此
//dir///subdir////file
与 相同/dir/subdir/file
。
因此,连接两个字符串以构建完整路径很简单:
full_path="$part1/$part2"
#!/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
简单地连接你的路径部分不会完成你想要的吗?
$ base="/home/user1/MyFolder/"
$ subdir="subFold1"
$ new_path=$base$subdir
$ echo $new_path
/home/user1/MyFolder/subFold1
然后,您可以根据需要创建文件夹/目录。
一种约定是用/
(eg /home/
) 结束目录路径,因为以 / 开头的路径可能与根目录混淆。如果在路径中使用双斜杠 ( //
),它仍然是正确的。但是,如果任何一个变量都没有使用斜线,则它是不正确的(例如/home/user1/MyFoldersubFold1
)。
以下脚本将多个(相对/绝对)路径 (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
我正在使用我的 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”命令总是会为你修剪终止斜线
#!/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 "$@"
这应该适用于空目录(您可能需要检查第二个字符串是否以/
应该被视为绝对路径的开头?):
#!/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 参数扩展