Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I'd like to check to see if a directory contains an array of file extensions. I'm on Ubuntu using Bash.

Something like :

files=$(ls $1/*)

extensions=$( txt pdf doc docx)

if [[ -e $files[@] contains $extenstions[@] ]] && echo "document exists" || 

echo "nothing found"
share|improve this question

Try this:

shopt -s nullglob
files=(*.txt *.pdf *.doc *.docx)
if [[ ${#files} -eq 0 ]]; then echo "nothing found"; fi

or

shopt -s nullglob extglob
files=(*.+(txt|pdf|doc|docx))
if [[ ${#files} -eq 0 ]]; then echo "nothing found"; fi

If you need files from all subdirectories too:

shopt -s nullglob extglob globstar
files=(**/*.+(txt|pdf|doc|docx))
if [[ ${#files} -eq 0 ]]; then echo "nothing found"; fi

From man bash:

nullglob: If set, bash allows patterns which match no files to expand to a null string, rather than themselves.

extglob: If set, the extended pattern matching features are enabled. See below.

globstar: If set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories.

Extended globbing:

?(pattern-list): Matches zero or one occurrence of the given patterns

*(pattern-list): Matches zero or more occurrences of the given patterns

+(pattern-list): Matches one or more occurrences of the given patterns

@(pattern-list): Matches one of the given patterns

!(pattern-list): Matches anything except one of the given patterns

share|improve this answer

Turn your list of extensions into a @(…|…) wildcard pattern.

shopt -s extglob nullglob
pattern='@('
for x in "${extensions[@]}"; do
  x=${x//"\\"//"\\\\"}; x=${x//"?"//"\\?"}; x=${x//"*"//"\\*"}; x=${x//"["//"\\["}
  pattern="$pattern$x|"
done
pattern="${pattern%\|})"
matches=(*.$pattern)
if ((${#matches[$@]})); then
  echo "There are matches"
fi

Alternatively (especially if you want to find files in subdirectories recursively), use find.

name_patterns=("(")
for x in "${extensions[@]}"; do
  x=${x//"\\"//"\\\\"}; x=${x//"?"//"\\?"}; x=${x//"*"//"\\*"}; x=${x//"["//"\\["}
  name_patterns+=(-name "*.$x" -o)
done
name_patterns[${#name_patterns[@]}]=")"
if [ -n "$(find dir "${name_patterns[@]}" | head -n 1)" ]; then
  echo "There are matches"
fi

Alternatively, use zsh.

matches=(*.$^extensions(NY1))
if ((#matches)); then
  echo "There are matches"
fi
share|improve this answer

find all the files in directory:

 #find all types of files
 PDFS=`find . -type f | grep pdf |wc -l`
 TXTS=`find . -type f | grep txt |wc -l`
 DOCS=`find . -type f | grep doc |wc -l`
 DOCXS=`find . -type f | grep docx |wc -l`
 SUM=$(( PDFS + TXTS + DOCS + DOCXS ))
 if [[ $SUM=0 ]] ; then 
    echo "not found"
 else
    echo "Some document found"

You can do other stuff like that , such as how many documents of type pdf found , or something like that.

You can also use grep -E to write just one expression for counting all types of files , with OR (|) condition. that will reduce to just one command.

Another easy option to count:

   numberoffiles=`find -name "*.pdf" -o -name "*.doc" -o name "*.txt"`
share|improve this answer
1  
find -name "*.pdf" -o -name "*.doc" -o name "*.txt" etc... – jasonwryan yesterday
    
yes , that is even more easy – Ijaz Khan yesterday
set   --                             ### init arg array
for e in txt pdf doc docx            ### outer loop for convenience
do    for  f in ./*."$e"             ### inner loop for files
      do   case  $f in (./\*"$e")    ### verify at least one match
           [ -e "$f" ];; esac &&     ### double-verify
           set  "$f" "$@"            ### prepend file to array
done; done                           ### double-done

When that completes all of the files will be in $1 and $2 and etc. The whole group can be referenced as a single string like "$*" or otherwise as a list of separate strings like "$@". The count can be had in "$#". And you can manipulate the arg array members with set (as above) or else w/ shift.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.