我有一个目录的路径,如下所示:
DIRNAME=/path/to/projects/proj1/dir1
我希望在projects
之后删除所有内容,但在文件路径中保留projects
。但是,此代码不起作用:
DIRNAME=/path/to/projects/proj1/dir1
My_Dir=projects
echo ${DIRNAME%$My_Dir*}
这会返回/path/to/
;我想要返回/path/to/projects
。文件路径中projects
之后的任何内容都不是静态的,因此不能在子字符串匹配中使用,如此示例所示。
强制性的旁注:我已阅读了十几个不同的页面,每个页面都包含子串操作的多个示例,但未能找到显示如何执行此操作的示例。我认为sed
可能会做这样的事情,但我没有看到任何这样做的例子。
答案 0 :(得分:2)
这通常是我在这种情况下拆分目录的方式:
DIRNAME=/path/to/projects/proj1/dir1
My_Dir=projects
PROJROOT=${DIRNAME%$My_Dir*}$My_Dir
PROJDIR=${DIRNAME#*$PROJROOT}
echo $DIRNAME
echo $PROJROOT
echo $PROJDIR
这个输出是:
/path/to/projects/proj1/dir1
/path/to/projects
/proj1/dir1
答案 1 :(得分:2)
您需要小心,但您可以使shell替换工作。例如:
keep="projects"
base="${DIRNAME%/$keep/*}/$keep"
请注意,/$keep/
部分可确保您使用/path/to/projects/with/remote_projects_here/to/confuse/you
获得正确的路径;你的原文会错误管理那个字符串。
您也可以使用sed
:
base=$(sed "s%\(.*/$keep\)/.*%\1%" <<< "$DIRNAME")
使用here string;或者你可以用echo
:
base=$(echo "$DIRNAME" | sed "s%\(.*/$keep\)/.*%\1%")
当然,您仍然可能会遇到子目录名称中的问题:
/path/to/projects/with/remote_projects_here/projects/select
测试代码:
#!/bin/bash
My_Dir=projects
keep="projects"
for dir in \
/path/to/projects/proj1/dir1 \
/path/to/projects/with/remote_projects_here/to/confuse/you
do
DIRNAME="$dir"
echo "Data"
echo "$DIRNAME"
echo "Original"
echo "${DIRNAME%$My_Dir*}"
echo "Variant 1"
base="${DIRNAME%/$keep/*}/$keep"
echo "$base"
echo "Variant 2"
base=$(sed "s%\(.*/$keep\)/.*%\1%" <<< "$DIRNAME")
echo "$base"
echo "Variant 3"
base=$(echo "$DIRNAME" | sed "s%\(.*/$keep\)/.*%\1%")
echo "$base"
done
示例输出:
Data
/path/to/projects/proj1/dir1
Original
/path/to/
Variant 1
/path/to/projects
Variant 2
/path/to/projects
Variant 3
/path/to/projects
Data
/path/to/projects/with/remote_projects_here/to/confuse/you
Original
/path/to/projects/with/remote_
Variant 1
/path/to/projects
Variant 2
/path/to/projects
Variant 3
/path/to/projects
输出可以更好地格式化,但它是重点。
答案 2 :(得分:0)
DIR=/path/to/projects/proj1/dir1
dirname "$DIR"
basename "$DIR"
输出
/path/to/projects/proj1
dir1
所以你可以用斜杠连接它们,你就完成了。我认为最简单的方法就是这样。