【问题标题】:How do I check if a directory has child directories?如何检查目录是否有子目录?
【发布时间】:2011-10-10 12:10:55
【问题描述】:

使用 bash,我如何编写 if 语句来检查存储在名为“$DIR”的脚本变量中的某个目录是否包含不是“.”的子目录还是“..”?

谢谢,- 戴夫

【问题讨论】:

标签: bash unix scripting


【解决方案1】:

试试这个作为你测试的条件:

subdirs=$(ls  -d $DIR/.*/ | grep -v "/./\|/../")

如果没有子目录,子目录将为空

【讨论】:

  • 嗨,我喜欢这个解决方案,因为它将内容放入一个数组中,我以后可以使用。但是 $DIR 变量在目录名称中包含一个空格,这似乎弄乱了表达式。
【解决方案2】:

正如 cmets 所指出的,过去 9 年情况发生了变化!点目录不再作为 find 的一部分返回,而是在 find 命令中指定的目录。

所以,如果您想继续使用这种方法:

#!/bin/bash
subdircount=$(find /tmp/test -maxdepth 1 -type d | wc -l)

if [[ "$subdircount" -eq 1 ]]
then
    echo "none of interest"
else
    echo "something is in there"
fi

(最初接受 2011 年的答案)

#!/usr/bin/bash
subdircount=`find /d/temp/ -maxdepth 1 -type d | wc -l`

if [ $subdircount -eq 2 ]
then
    echo "none of interest"
else
    echo "something is in there"
fi

【讨论】:

  • @AI G 当我尝试上述find 命令时,如果不存在子文件夹,它会返回文件夹路径/d/temp./../ 未计算在内。
  • @Antarus 我也一样。给定的这个解决方案对我不起作用。对于一个空目录,我得到 1 的结果,对于每个存在的目录,我得到一个结果(例如,如果有 2 个子目录,则结果为 3)。我正在使用 git bash,所以我猜这不是“正确”的 bash...
【解决方案3】:

怎么样:

num_child=`ls -al $DIR | grep -c -v ^d`

如果 $num_child > 2,那么你有子目录。如果您不想隐藏目录,请将 ls -al 替换为 ls -l。

if [ $num_child -gt 2 ]
then
    echo "$num_child child directories!"
fi

【讨论】:

  • ls 的输出是否跨各种 unixoid 系统标准化?
  • 据我所见(linux / opensolaris / freebsd),是的。
  • 是的,它是标准的。请参阅规范here。以前的版本说同样的here。 A 会猜测标准的第一个版本 (POSIX) 也是这样说的,但我找不到。
【解决方案4】:

我不太确定你想在这里做什么,但你可以使用find

find /path/to/root/directory -type d

如果你想编写脚本:

find $DIR/* -type d

应该可以解决问题。

【讨论】:

  • 这也找到了根目录,而不仅仅是子目录
  • 试试find /path/to/root/directory -mindepth 1 -type d
【解决方案5】:

纯 bash 中的解决方案,无需任何其他程序执行。这不是最紧凑的解决方案,但如果在循环中运行,它可能会更有效,因为不需要创建进程。如果'$dir' 中有很多文件,文件名扩展可能会中断。

shopt -s dotglob   # To include directories beginning by '.' in file expansion.
nbdir=0
for f in $dir/*
do
  if [ -d $f ]
  then
    nbdir=$((nbdir+1))
  fi
done

if [ nbdir -gt 0 ]
then
   echo "Subdirs"
else
   echo "No-Subdirs"
fi

【讨论】:

    【解决方案6】:

    这是一个更简约的解决方案,它将在一行中执行测试..

    ls $DIR/*/ >/dev/null 2>&1 ; 
    
    if [ $? == 0 ]; 
    then 
      echo Subdirs
    else 
      echo No-subdirs
    fi
    

    通过将/ 放在* 通配符之后,您只选择目录,因此如果没有目录,则ls 返回错误状态2 并打印消息ls: cannot access <dir>/*/: No such file or directory2>&1 捕获 stderr 并将其通过管道传输到 stdout 中,然后将整个部分通过管道传输到 null (这消除了常规的 ls 输出也有文件时)。

    【讨论】:

    • 更简约:ls $DIR/*/ &>/dev/null && echo Subdirs || echo No-subdirs
    • @ingydotnet 除了 if/else 位实际上不是解决方案的一部分。它只是演示了“$?”变量。不错的速记!
    • @ingydotnet 但是,该解决方案是否可移植到其他 shell,例如 ksh?
    • 绝对的极简主义和跨shell兼容是将以下内容放入函数ls $1/*/ >/dev/null 2>&1
    【解决方案7】:

    在我的情况下,它不像 @AIG 所写的那样工作 - 对于空目录,我得到 subdircount=1(find 只返回 dir 本身)。

    什么对我有用:

    #!/usr/bin/bash
    subdircount=`find /d/temp/ -maxdepth 1 -type d | wc -l`
    if [ $subdircount -ge 2 ]
    then
        echo "not empty"
    else
        echo "empty"
    fi
    

    【讨论】:

      【解决方案8】:

      这是您在这个问题上看到的最佳答案。

      function hasDirs ()
      {
          declare $targetDir="$1"    # Where targetDir ends in a forward slash /
          ls -ld ${targetDir}*/
      }
      

      如果你已经在目标目录中:

      if hasDirs ./
      then
      
      fi
      

      如果您想了解另一个目录:

      if hasDirs /var/local/   # Notice the ending slash
      then
      
      fi
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-18
        • 2011-04-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 1970-01-01
        • 2018-05-08
        相关资源
        最近更新 更多