当前位置:  开发笔记 > 编程语言 > 正文

如果目录包含文件,则从shell脚本进行检查

如何解决《如果目录包含文件,则从shell脚本进行检查》经验,为你挑选了8个好方法。

从shell脚本,如何检查目录是否包含文件?

类似的东西

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

但是如果目录包含一个或多个文件(上面的文件仅适用于0或1个文件),则可以使用.



1> olibre..:
三个最好的技巧

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 -prunefind -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

最后一个代码适用于大多数情况但要注意恶意路径可以表达命令......


我认为你可以将find选项简化为`[-n"$(find"your/dir"-prune -empty)"]`,以避免重复目录路径.

2> Bruno De Fra..:

该解决方案使用至今ls.这是一个全bash解决方案:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi


为什么不使用子shell重置设置:`files = $(shopt -s nullglob; shopt -s dotglob; echo/some/dir/*)`
只要你记得在脚本结尾处将选项设置回原始值:)
@teambob如果使用子shell:`files = $(shopt -s nullglob; shopt -s dotglob; echo/some/dir/*)`那么if语句应该改为`if [$ {#files} -gt 0];`或者你可能只是忘记了子shell命令周围的()?`files =($(shopt -s nullglob; shopt -s dotglob; echo/some/dir/*))`
@stoutyhk $(...)恢复设置,不需要单独的子shell.使用$(...)生成一个shell的新实例.命令完成后,该新实例的环境将被丢弃.编辑:找到参考tldp.org/LDP/abs/html/commandsub.html"命令替换调用子shell."

3> mweerden..:

以下内容如何:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

这样就不需要生成目录内容的完整列表.这read两者都是为了丢弃输出并使表达式仅在读取某些内容时被评估为真(即被/some/dir/发现为空find).


然而,它确实依赖于非标准的`-maxdepth`和`-empty`原色.
+1这是最优雅的解决方案.它不涉及解析`ls`输出,也不依赖于非默认的shell特性.
或者只是`find/some/dir/-maxdepth 0 -empty -exec echo"huzzah"\;`

4> Greg Hewgill..:

尝试:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi


您可以使用`-n`代替`!-z`(它们都是等价的,但为什么不在它存在时使用较短的形式).

5> 小智..:

注意包含大量文件的目录!评估ls命令可能需要一些时间.

IMO最好的解决方案就是使用它

find /some/dir/ -maxdepth 0 -empty



6> 小智..:
# 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
}



7> Andrew Taylo..:
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi



8> DGM..:

你能比较一下它的输出吗?

 ls -A /some/dir | wc -l

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有