从文件路径

时间:2015-12-16 00:37:21

标签: bash

我有一个目录的路径,如下所示:

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可能会做这样的事情,但我没有看到任何这样做的例子。

3 个答案:

答案 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 

所以你可以用斜杠连接它们,你就完成了。我认为最简单的方法就是这样。