检查目录中是否包含另一个目录

5

如何在shell中检查给定的目录是否包含另一个目录。我想传递2个完整路径目录。(我知道这很愚蠢,但只是为了学习目的)。然后,我想看看这两个路径中的任何一个是否包含在另一个中。

parent=$1
child=$2

if [ -d $child ]; then
    echo "YES"
else
    echo "NO"
fi

这个操作并没有使用到父目录,只是检查子目录是否存在。


你想要查看$parent是否为某个层级的$child的父级吗?这是一个字符串前缀检查(假设您不担心符号链接,../游戏等)。 - Etan Reisner
使用 find -type d -name "$child" - Barmar
6个回答

7
您可以使用find查看一个名称是否包含在另一个名称中:
result=$(find "$parent" -type d -name "$child")
if [[ -n $result ]]
then echo YES
else echo NO
fi

1

类似于Barmar的回答,但比名称比较更可靠:

if find "$parent" -samefile "$child" -printf 'Y\n' -quit | grep -qF Y; then
    echo "contains '$child'"
fi

为了更加安全,您还可以跟随符号链接以确保递归操作对$parent不会损坏$child或其中的任何内容:
if find -L "$parent" -samefile "$child" -printf 'Y\n' -quit | grep -qF Y; then
    echo "contains '$child' or link thereto"
fi

0
创建一个文件(例如:dircontains.sh),并添加以下代码:
#!/bin/bash

function dircontains_syntax {
    local msg=$1
    echo "${msg}" >&2
    echo "syntax: dircontains <parent> <file>" >&2
    return 1
}

function dircontains {
    local result=1
    local parent=""
    local parent_pwd=""
    local child=""
    local child_dir=""
    local child_pwd=""
    local curdir="$(pwd)"
    local v_aux=""

    # parameters checking
    if [ $# -ne 2 ]; then
        dircontains_syntax "exactly 2 parameters required"
        return 2
    fi
    parent="${1}"
    child="${2}"

    # exchange to absolute path
    parent="$(readlink -f "${parent}")"
    child="$(readlink -f "${child}")"
    dir_child="${child}"

    # direcory checking
    if [ ! -d "${parent}" ];  then
        dircontains_syntax "parent dir ${parent} not a directory or doesn't exist"
        return 2
    elif [ ! -e "${child}" ];  then
        dircontains_syntax "file ${child} not found"
        return 2
    elif [ ! -d "${child}" ];  then
        dir_child=`dirname "${child}"`
    fi

    # get directories from $(pwd)
    cd "${parent}"
    parent_pwd="$(pwd)"
    cd "${curdir}"  # to avoid errors due relative paths
    cd "${dir_child}"
    child_pwd="$(pwd)"

    # checking if is parent
    [ "${child_pwd:0:${#parent_pwd}}" = "${parent_pwd}" ] && result=0

    # return to current directory
    cd "${curdir}"
    return $result
}    

然后运行这些命令

. dircontains.sh

dircontains path/to/dir/parent any/file/to/test

# the result is in $? var 
# $1=0, <file> is in <dir_parent>
# $1=1, <file> is not in <dir_parent>
# $1=2, error

注意:
- 仅在Ubuntu 16.04 / bash中进行了测试
- 在此情况下,第二个参数可以是任何Linux文件


0

纯Bash,没有使用外部命令:

#!/bin/bash

parent=$1
child=$2
[[ $child && $parent ]] || exit 2 # both arguments must be present
child_dir="${child%/*}"           # get the dirname of child
if [[ $child_dir = $parent && -d $child ]]; then
  echo YES
else
  echo NO
fi

0

适用于子目录:

parent=$1
child=$2

if [[ ${child/$parent/} != $child ]] ; then
    echo "YES"
else
    echo "NO"
fi

-1
你可以在纯bash中完成这个。循环遍历$1中的每个文件,并检查"$1/$2"是否为目录,如下所示:
parent=$1
child=$(basename $2)
if [ -d $parent ] && [ -d $child ]; then
    for child in $parent; do
        if [ -d "$parent/$child" ]; then
            echo "Yes"
        else
            echo "No"
        fi
    done
fi

1
这个方法行不通的原因是因为在第二个if语句中,你将整个子路径附加到父路径上。这会导致一个不存在的目录,并且它总是返回NO。 - Rumen Hristov
1
@Kanny Bros,如果您只想要$child的文件夹名称而不是其绝对路径,请使用child=$(basename $2) - MeetTitan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接