我需要使用bash检查目录中是否存在文件。我已经尝试了以下方法,但它需要完整的路径作为输入。
if [ -e /*/my_file.txt ] ;
then
echo "file found"
else
echo "not found"
fi
有没有什么方法可以让我动态地检查文件是否存在于任何深度。注意:我不想使用"find",因为它需要很多时间来执行。
如果您使用bash
4,您可以编写递归下降层次结构的模式:
shopt -s globstar
for f in /**/myfile.txt; do
if [[ -e $f ]]; then
found=1
echo "File found"
break
fi
done
if [[ $found -ne 1 ]]; then
echo "File not found"
fi
使用find
:
found=$( find / -name myfile.txt )
if [[ -n $found ]]; then
echo "File found"
else
echo "File not found"
fi
如果您真正关心的是速度,那么像ls * */* */*/*
这样的文件globbing对您没有太大帮助。这个错误有其局限性:参数列表太长。find
是一个很有用的工具。它非常灵活。但是,就像使用文件globbing一样,每次调用都必须扫描目录树。对于偶尔的搜索,比如维护,这是完全可以接受的。但如果这是零件加工流水线,速度是不可接受的。为此,您需要一个优化的数据库。
简单化的方式
我所知道的大多数UNIX都附带了locate
。
如果它是预装的,你可以这样搜索:
$ locate -b 'my_file.txt'
my_file.txt
前面的反斜杠是有意的。它关闭通配符搜索。添加-i
可以进行不区分大小写的搜索。
如果该命令不可用,则应该可以从操作系统存储库中进行安装。对于Debian/Ubuuntu:apt install locate
。对于第一个init,以root用户身份或使用sudo运行/etc/cron.daily/locate
。
数据库每天更新。对于某些应用程序,此间隔可能太长。通过将cronjob从每天移动到每3小时点赞,您可以获得更新的结果。
实时方式
这有点超出了这个答案的范围。但您需要某种deamon,它可以监视内核的inotify事件以了解目录更改。这些反过来会反映在一个数据库中,可以通过一些API进行查询。就像MacOS的Spotlight或Gnome的Tracker。
find
是合适的解决方案。
但是,您可以使用bash扩展功能
if ls */* | grep -q my_file.txt
then echo file found
else echo file not found
fi
纸币
- 如果是顶级的话,上述解决方案将找不到CCD_
- 如果
my_file.txt
是目录名的一部分,则可能会得到错误的结果 - 如果有许多(数千)目录和许多文件/扩展可能会受到粘贴bash限制(arg列表太长)
- 您可以在上述限制状态下使用
ls * */* */*/* | grep