【问题标题】:Check if folder contains glob检查文件夹是否包含 glob
【发布时间】:2017-04-13 22:19:21
【问题描述】:

在我的 Mac 上,我试图找出一种方法来检查已安装的卷到服务器,以查看目录是否通过 shell 脚本接收日志文件,该脚本将在launchd 中使用,设置为时间间隔。

从我的搜索和历史上我使用过:

$DIR="/path/to/file"
THEFILES=(`find ./ -maxdepth 1 -name "*.log"`)
if [ ${#THEFILES[@]} -gt 0 ]; then 
    echo "exists"
else
    echo "nothing"
fi

如果 shell 脚本放置在该特定目录中并且文件存在。但是,当我将脚本移出该目录并尝试时:

THEFILES=(`find ./ -maxdepth 1 -name "*.log"`)
cd $DIR
if [ ${#THEFILES[@]} -gt 0 ]; then 
    echo "exists"
else
    echo "nothing"
fi

我得到nothing 的恒定回报。我认为这可能与深度有关,所以我将-maxdepth 1 更改为-maxdepth 0,但我仍然得到nothing。通过搜索,我遇到了“Check whether a certain file type/extension exists in directory”并尝试:

THEFILES=$(ls "$DIR/.log" 2> /dev/null | wc -l)
echo $THEFILES

但我返回了一个常量0。当我进一步搜索时,我遇到了“Checking from shell script if a directory contains files”并尝试了使用find 的变体:

THEFILES=$(find "$DIR" -type f -regex '*.log')
cd $DIR
if [ ${#THEFILES[@]} -gt 0 ]; then 
    echo "exists"
else
    echo "nothing"
fi

返回空白。当我尝试时:

if [ -n "$(ls -A $DIR)" ]; then
    echo "exists"
else
    echo "nothing"
fi

我得到一个空白终端返回。在这个answer 上,我的Mac 上没有pruneshopt。那么如何检查已安装服务器的目录以查看是否存在具有特定扩展名且不会从隐藏文件中返回错误的特定文件?

编辑:

根据评论,我尝试删除深度:

THEFILES=$(find ./ -name "*.log")

但我得到一个空白返回,但如果我将 .log 文件放在那里,它会运行,但我不明白为什么 else 不返回 nothing,除非它正在考虑隐藏文件。感谢l'L'l,我了解到-prunefind 的实用程序中,但是当我尝试时:

if [ -n "$(find $DIR -prune -empty -type d)" ]; then

当存在 LOG 文件时,我会不断返回 nothing

【问题讨论】:

  • 您正在使用-maxdepth 限制命令遍历的距离;听起来这可能是问题所在。此外,prune 包含在 Mac 的 find 实用程序中...
  • 这个find ./ -maxdepth 1 -name "*.log当前目录(脚本所在的位置)搜索。如果你把它移到外面,当然,它是行不通的。使用完整路径名,例如find /full/path/name/to/dir -maxdepth.... etc
  • 也许可以试试find "$DIR" -name "*.log" | wc -l。您的许多命令都在抑制输出,或者以不会返回任何内容的方式进行设置。
  • 我无法确定您要查找的内容。你有目录,你只想看看*.log 是否存在于该目录中?
  • @miken32 是正确的。每隔 5 分钟通过一个应用程序,我想检查目录中是否存在日志文件。

标签: bash macos shell


【解决方案1】:

内置的 Bash compgen“根据选项显示可能的完成”并且是 typically used for autocomplete scripts,但也可以用于此目的。默认输出完成列表,所以重定向到/dev/null

#!/bin/bash
dir=/some/log/dir
if compgen -G "$dir/*.log" > /dev/null; then
    # do stuff
fi

【讨论】:

  • 以前从未听说过或使用过compgen 的有趣方法,答案+1。
  • 这是一个巧妙的技巧 - 在检测目录是否为空的情况下,我冒昧地将其改编为 this answer(需要一种解决方法来检测 hidden 个项目)。
【解决方案2】:

您提出的每个答案都非常接近工作!

我没有使用-maxdepth 选项,如果只检查$DIR 下的文件而不是其子目录对您很重要,请随时将-maxdepth 1 添加到对find 的任何调用中。

使用 mklement0 所指向的小写变量以避免与环境变量发生冲突。

回答 1

您设置了dir,但改用./...

dir="/path/to/dir"
# Create an array of filenames
files=( $(find "$dir" -name "*.log") )
if [ ${#files[@]} -gt 0 ]; then # if the length of the array is more than 0
    echo "exists"
else
    echo "nothing"

回答 2

你在运行 find... 后使用 cd $dir...

dir="path/to/dir"
cd "$dir"
files=( $(find -name "*.log") )
if [ ${#files[@]} -gt 0 ]; then
    echo "exists"
else
    echo "nothing"
fi

答案 3

您在“.log”之前忘记了一个“*”...查看globbing 的文档

dir="/path/to/dir"
# print all the files in "$DIR" that end with ".log"
# and count the number of lines
nbfiles=$(ls "$dir/"*.log 2> /dev/null | wc -l) # nbfiles is an integer
if [ $nbfiles -gt 0 ]; then
    echo "exists"
else
    echo "nothing
fi

答案 4

find 的 macOS 手册页建议正则表达式默认使用基本正则表达式:

-E

解释后跟 -regex 和 -iregex 的正则表达式 选项作为扩展(现代)正则表达式而不是 基本正则表达式 (BRE)。

您在 * 之前缺少 .cd $dir 不是必需的,因为您将 $dir 作为参数传递给 find ;并且您不会将find 的输出存储在数组中,因此您无法检查数组的长度。

# The output of find is stored as a string
files=$(find "/path/to/dir" -type f -regex '.*\.log')
if [ -n "$files" ]; then # Test that the string $files is not empty
    echo "exists"
else
    echo "nothing"
fi

【讨论】:

  • 这是更正总结,不是答案。为什么不直接修正答案?
猜你喜欢
  • 2015-09-14
  • 2014-05-10
  • 2018-07-17
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-17
相关资源
最近更新 更多