Linux 如何连接两个字符串以构建完整路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11226322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to concatenate two strings to build a complete path
提问by Hakim
I am trying to write a bash script. In this script I want user to enter a path of a directory. Then I want to append some strings at the end of this string and build a path to some subdirectories. For example assume user enters an string like this:
我正在尝试编写一个 bash 脚本。在这个脚本中,我希望用户输入目录的路径。然后我想在这个字符串的末尾附加一些字符串并建立一个到一些子目录的路径。例如,假设用户输入这样的字符串:
/home/user1/MyFolder
Now I want to create 2 subdirectories in this directory and copy some files there.
现在我想在这个目录中创建 2 个子目录并在那里复制一些文件。
/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2
How can I do this?
我怎样才能做到这一点?
回答by Levon
Won't simply concatenating the part of your path accomplish what you want?
简单地连接路径的一部分不会完成你想要的吗?
$ base="/home/user1/MyFolder/"
$ subdir="subFold1"
$ new_path=$base$subdir
$ echo $new_path
/home/user1/MyFolder/subFold1
You can then create the folders/directories as needed.
然后,您可以根据需要创建文件夹/目录。
One convention is to end directory paths with /
(e.g. /home/
) because paths starting with a / could be confused with the root directory. If a double slash (//
) is used in a path, it is also still correct. But, if no slash is used on either variable, it would be incorrect (e.g. /home/user1/MyFoldersubFold1
).
一种约定是以/
(eg /home/
)结束目录路径,因为以 / 开头的路径可能会与根目录混淆。如果//
在路径中使用双斜杠 ( ),它仍然是正确的。但是,如果任何一个变量都没有使用斜杠,那将是不正确的(例如/home/user1/MyFoldersubFold1
)。
回答by Sean Bright
#!/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
And if you want to use readline so you get completion and all that, add a -e
to the call to read
:
如果您想使用 readline 来完成所有这些,请-e
在调用中添加一个read
:
read -e -p "Enter a directory: " BASEPATH
回答by ormaaj
#!/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 "$@"
回答by Dunes
The POSIX standard mandates that multiple /
are treated as a single /
in a file name. Thus
//dir///subdir////file
is the same as /dir/subdir/file
.
POSIX 标准要求在文件名中将多个/
视为一个/
。因此
//dir///subdir////file
与 相同/dir/subdir/file
。
As such concatenating a two strings to build a complete path is a simple as:
因此,连接两个字符串以构建完整路径很简单:
full_path="$part1/$part2"
回答by Carlo Wood
The following script catenates several (relative/absolute) paths (BASEPATH) with a relative path (SUBDIR):
以下脚本将多个(相对/绝对)路径 (BASEPATH) 与相对路径 (SUBDIR) 联系起来:
shopt -s extglob
SUBDIR="subdir"
for BASEPATH in '' / base base/ base// /base /base/ /base//; do
echo "BASEPATH = \"$BASEPATH\" --> ${BASEPATH%%+(/)}${BASEPATH:+/}$SUBDIR"
done
The output of which is:
其输出为:
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:
在shopt -s extglob
仅需要允许基本路径,结束对多个斜线(这可能是无义)。没有扩展的globing,你可以只使用:
echo ${BASEPATH%%/}${BASEPATH:+/}$SUBDIR
which would result in the less neat but still working:
这将导致不那么整洁但仍然有效:
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
回答by tsl0922
This should works for empty dir (You may need to check if the second string starts with /
which should be treat as an absolute path?):
这应该适用于空目录(您可能需要检查第二个字符串/
是否应该被视为绝对路径?):
#!/bin/bash
join_path() {
echo "${1:+/}" | sed 's#//#/#g'
}
join_path "" a.bin
join_path "/data" a.bin
join_path "/data/" a.bin
Output:
输出:
a.bin
/data/a.bin
/data/a.bin
Reference: Shell Parameter Expansion
参考:Shell 参数扩展
回答by u11265208
I was working around with my shell script which need to do some path joining stuff like you do.
我正在处理我的 shell 脚本,它需要像你一样做一些路径连接。
The thing is, both path like
问题是,两条路径都像
/data/foo/bar
/data/foo/bar/
are valid.
是有效的。
If I want to append a file to this path like
如果我想将文件附加到此路径,例如
/data/foo/bar/myfile
there was no native method (like os.path.join() in python) in shell to handle such situation.
shell 中没有本地方法(如 python 中的 os.path.join())来处理这种情况。
But I did found a trick
但我确实找到了一个技巧
For example , the base path was store in a shell variable
例如,基本路径存储在一个shell变量中
BASE=~/mydir
and the last file name you wanna join was
你想加入的最后一个文件名是
FILE=myfile
Then you can assign your new path like this
然后你可以像这样分配你的新路径
NEW_PATH=$(realpath ${BASE})/FILE
and then you`ll get
然后你会得到
$ echo $NEW_PATH
/path/to/your/home/mydir/myfile
the reason is quiet simple, the "realpath" command would always trim the terminating slash for you if necessary
原因很简单,如有必要,“realpath”命令将始终为您修剪终止斜杠