在bash中搜索文件存在于任何深度

时间:2016-07-29 10:43:53

标签: bash shell file grep find

我需要使用bash检查目录中是否存在文件。我尝试了下面的方法,但它需要完整的路径作为输入。

if [ -e /*/my_file.txt ] ;
then
  echo "file found"
else
  echo "not found"
fi

有什么办法可以动态检查文件是否存在于任何深度。 注意:我不想使用“查找”,因为执行需要很多时间。

3 个答案:

答案 0 :(得分:1)

如果您使用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

答案 1 :(得分:0)

如果您真的关心速度,像 ls * */* */*/* 这样的文件通配符对您没有多大帮助。它有这个错误的限制:参数列表太长。 find 是查找资料的有用工具。它非常灵活。但是就像使用文件通配符一样,它必须在每次调用时扫描目录树。对于偶尔的搜索,比如维护,这是完全可以接受的。但是如果这是零件加工流水线,速度是不能接受的。为此,您需要一个优化的数据库。

简单的方法

我所知道的大多数 UNIX 都附带 locate

如果是预安装,你可以这样搜索:

$ locate -b '\my_file.txt'

my_file.txt 前面的反斜杠是有意的。它关闭通配符搜索。添加 -i 提供不区分大小写的搜索。

如果命令不可用,它应该可以从您的操作系统存储库安装。对于 Debian/Ubuntu:apt install locate。对于第一次 init 以 root 身份或使用 sudo 运行 /etc/cron.daily/locate

数据库每天更新。对于某些应用程序,此间隔可能太长。通过将定时任务从每天改为每 3 小时一次,您可以获得更多最近的结果。

实时方式...

这有点超出本答案的范围。但是您需要某种守护进程,它会监视内核 inotify 事件以进行目录更改。这些反过来会反映在数据库中,可以通过一些 API 查询。就像 MacOS 的 Spotlight 或 Gnome 的 Tracker。

答案 2 :(得分:-1)

find是正确的解决方案。

但是你可以使用bash扩展功能

if ls */* | grep -q my_file.txt
then echo file found
else echo file not found
fi

注意

  • 如果是最高级别,则上述解决方案将无法找到my_file.txt
  • 如果my_file.txt是目录名称的一部分,则可能会得到错误的结果。
  • 如果有多个(数千个)目录和许多文件 / 扩展可能会获得粘贴bash限制(arg列表太长)
  • 您可以ls * */* */*/* | grep以上限制状态。