从shell脚本,如何检查目录是否包含文件?
类似的东西
if [ -e /some/dir/* ]; then echo "huzzah"; fi;
但是如果目录包含一个或多个文件(上面的文件仅适用于0或1个文件),则可以使用.
oli*_*bre 132
shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))这个技巧是100%bash并调用(生成)一个子shell.这个想法来自Bruno De Fraine,并通过teambob的评论进行了改进.
files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
  echo "contains files"
else 
  echo "empty (or does not exist or is a file)"
fi
注意:空目录和不存在目录之间没有区别(即使提供的路径是文件).
在#bash IRC频道的"官方"常见问题解答中有一个类似的替代方案和更多细节(以及更多示例):
if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi
[ -n "$(ls -A your/dir)" ]这个技巧的灵感来自于2007年发布的nixCraft的文章.添加2>/dev/null以抑制输出错误"No such file or directory".
另请参阅Andrew Taylor的回答(2008)和gr8can8dian的回答(2011).
if [ -n "$(ls -A your/dir 2>/dev/null)" ]
then
  echo "contains files (or is a file)"
else
  echo "empty (or does not exist)"
fi
或单行基础版本:
[[ $(ls -A your/dir) ]] && echo "contains files" || echo "empty"
注意: 当目录不存在时ls返回$?=2.但是文件和空目录之间没有区别.
[ -n "$(find your/dir -prune -empty)" ]这最后绝招是从灵感gravstar的答案在那里-maxdepth 0被替换-prune和改进菲尔斯的评论.
if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi
变种使用-type d:
if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
  echo "empty directory"
else
  echo "contains files (or does not exist or is not a directory)"
fi
说明:
find -prune与find -maxdepth 0使用较少的字符相似find -empty 打印空目录和文件find -type d 仅打印目录注意:您也可以[ -n "$(find your/dir -prune -empty)" ]只使用下面的缩短版本进行替换:
if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi
最后一个代码适用于大多数情况但要注意恶意路径可以表达命令......
Bru*_*ine 63
该解决方案使用至今ls.这是一个全bash解决方案:
#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
mwe*_*den 48
以下内容如何:
if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi
这样就不需要生成目录内容的完整列表.这read两者都是为了丢弃输出并使表达式仅在读取某些内容时被评估为真(即被/some/dir/发现为空find).
Gre*_*ill 21
尝试:
if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
小智 14
注意包含大量文件的目录!评估ls命令可能需要一些时间.
IMO最好的解决方案就是使用它
find /some/dir/ -maxdepth 0 -empty
小智 14
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi
小智 5
这可能是一个非常晚的回应,但这是一个有效的解决方案。此行仅识别文件的存在!如果目录存在,它不会给您误报。
if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi
这告诉我该目录是否为空,如果不是,它包含的文件和目录的数量。
directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)
if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi
警告:如果目录不存在,此命令将失败。
我知道这个问题被标记为 bash;但是,仅供参考,对于zsh用户:
检查是否foo非空:
$ for i in foo(NF) ; do ... ; done
其中,如果foo非空,for则将执行块中的代码。
检查是否foo为空:
$ for i in foo(N/^F) ; do ... ; done
其中,如果为空,则将执行块foo中的代码。for
我们不需要引用foo上面的目录,但如果需要的话我们可以这样做:
$ for i in 'some directory!'(NF) ; do ... ; done
我们还可以测试多个对象,即使它不是一个目录:
$ mkdir X     # empty directory
$ touch f     # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done  # echo empty directories
X
任何不是目录的内容都将被忽略。
由于我们是通配符,我们可以使用任何通配符(或大括号扩展):
$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf                    # create regular file
$ touch X1/f                  # directory X1 is not empty
$ touch Y1/.f                 # directory Y1 is not empty
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo  # print empty directories
X X2 Y Y2
我们还可以检查放置在数组中的对象。以上述目录为例:
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*)                     # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z
因此,我们可以测试可能已经在数组参数中设置的对象。
请注意,显然,块中的代码for是依次在每个目录上执行的。如果这不合需要,那么您可以简单地填充一个数组参数,然后对该参数进行操作:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
对于 zsh 用户,有(F)glob 限定符(参见 参考资料man zshexpn),它匹配“完整”(非空)目录:
$ mkdir X Y
$ touch Y/.f        # Y is now not empty
$ touch f           # create a regular file
$ ls -dF *          # list everything in the current directory
f X/ Y/
$ ls -dF *(F)       # will list only "full" directories
Y/
限定符(F)列出匹配的对象:是目录并且不为空。因此,(^F)匹配:不是目录或为空。因此,(^F)例如,单独也会列出常规文件。因此,正如zshexp手册页上所解释的,我们还需要(/)glob 限定符,它仅列出目录:
$ mkdir X Y Z
$ touch X/f Y/.f    # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z
因此,要检查给定目录是否为空,您可以运行:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
只是为了确保不会捕获非空目录:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
哎呀!由于Y不为空,zsh 找不到(/^F)(“空目录”)的匹配项,因此会输出一条错误消息,指出未找到 glob 的匹配项。因此,我们需要使用(N)glob 限定符来抑制这些可能的错误消息:
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
因此,对于空目录,我们需要限定符(N/^F),您可以将其读作:“不要警告我失败,目录未满”。
类似地,对于非空目录,我们需要限定符(NF),我们同样可以将其读作:“不要警告我失败,完整目录”。