Check if folder contains glob

2019-07-14 11:25发布

On my Mac I am trying to figure out a way to check a mounted volume to a server to see if the directory receives a log file through a shell script that will be used in launchd set to a time interval.

From my searches and historically I've used:

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

If the shell script is placed inside that particular directory and the files are present. However, when I move the script outside of that directory and try:

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

I get a constant return of nothing. I thought it might be in regards to the depth so I changed -maxdepth 1 to -maxdepth 0 but I still get nothing. Through searching I ran across "Check whether a certain file type/extension exists in directory" and tried:

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

but I'm returned a constant 0. When I searched further I ran across "Checking from shell script if a directory contains files" and tried a variation using find with:

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

with a blank return. When I try:

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

I get a blank terminal returned. On this answer I dont have prune or shopt on my Mac. So how I can I check a mounted server's directory to see if a particular file with a specific extension exists that will not give a false return from hidden files?

EDIT:

Per comment I tried removing the depth with:

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

but I get a blank return but if I drop a .log file in there it runs but I don't understand why else isn't returning nothing unless it's considering the hidden files. Thanks to l'L'l I learned -prune was in find's utility but when I try:

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

I get a constant return of nothing when there is a LOG file present.

标签: bash macos shell
2条回答
Rolldiameter
2楼-- · 2019-07-14 11:58

Each of your proposed answer is really close to working!

I didn't use the -maxdepth option, if it is important to you to only check the files under $DIR but not its subdirectories, feel free to add -maxdepth 1 to any call to find.

Use lowercase variables as pointed by mklement0 to avoid conflicts with environment variables.

Answer 1

You set dir, but use ./ instead...

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"

Answer 2

You use cd $dir after running find...

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

Answer 3

you forgot a '*' before the '.log'... Have a look a the documentation for 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

Answer 4

The macOS man page of find suggests that regex uses Basic Regular Expressions by default:

-E

Interpret regular expressions followed by -regex and -iregex options as extended (modern) regular expressions rather than basic regular expressions (BRE's).

You are missing a . before the * ; the cd $dir is not necessary since you pass $dir as an argument to find ; and you don't store the output of find in an array, so you can't check the length of the array.

# 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
查看更多
beautiful°
3楼-- · 2019-07-14 12:06

The Bash builtin compgen "displays possible completions based on the options" and is typically used for autocomplete scripts, but can be used for this purpose also. By default it outputs the completion list, so redirect it to /dev/null.

#!/bin/bash
dir=/some/log/dir
if compgen -G "$dir/*.log" > /dev/null; then
    # do stuff
fi
查看更多
登录 后发表回答