Check if a specific file type / extension exists in the directory

How would you tell if there are files of a certain extension in the directory, bash?

Something like

if [ -e *.flac ]; then echo true; fi 
+46
linux bash shell
04 Oct '10 at 15:37
source share
10 answers
 #!/bin/bash count=`ls -1 *.flac 2>/dev/null | wc -l` if [ $count != 0 ] then echo true fi 
+55
04 Oct 2018-10-10
source share
 #/bin/bash myarray=(`find ./ -maxdepth 1 -name "*.py"`) if [ ${#myarray[@]} -gt 0 ]; then echo true else echo false fi 
+10
Oct 04 2018-10-10
source share

This uses ls (1) if flac files do not exist, ls reports an error and the script exits; othewise script continues and files can be processed

 #! /bin/sh ls *.flac >/dev/null || exit ## Do something with flac files here 
+8
Oct 05 2018-10-10 at
source share
 shopt -s nullglob if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ] then echo true fi 
+7
Oct 04 2018-10-10
source share

You need to be careful which flag you enter in your if , and how it relates to the desired result.

If you want to check only ordinary files , and not other types of records in the file system, you need to change the code skeleton to:

 if [ -f file ]; then echo true; fi 

Using -f limits if regular files, while -e is more expansive and matches all types of entries in the file system. Of course, there are other options, such as -d for directories, etc. See http://tldp.org/LDP/abs/html/fto.html for a good listing.

As @msw pointed out, test (i.e. [ ) will suffocate if you try to submit more than one argument. This can happen in your case if glob for *.flac returned more than one file. In this case, try wrapping the if test in a loop, for example:

 for file in ./*.pdf do if [ -f "${file}" ]; then echo 'true'; break fi done 

That way, you break in the first instance of the file extension you want, and you can continue to work with the rest of the script.

+2
04 Oct 2018-10-10
source share
 #!/bin/bash files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l) if [ "$files" != "0" ] then echo "Some files exists." else echo "No files with that extension." fi 
+2
04 Oct '10 at 15:50
source share
  shopt -s nullglob set -- $(echo *.ext) if [ "${#}" -gt 0 ];then echo "got file" fi 
+2
04 Oct 2018-10-10
source share

The top solution (if [ -e *.flac ];) did not work for me, giving: [: too many arguments

if ls *.flac >/dev/null 2>&1; then it will work.

+2
Nov 05 '15 at 10:55
source share

bash:

 any_with_ext () ( ext="$1" any=false shopt -s nullglob for f in *."$ext"; do any=true break done echo $any ) if $( any_with_ext flac ); then echo "have some flac" else echo "dir is flac-free" fi 

I use parentheses instead of curly braces to ensure that a subshell is used (don't want to compress the current nullglob setting).

+1
04 Oct 2018-10-10
source share

Here is a solution that does not use external commands (i.e. no ls ), but instead uses a shell function. Tested in bash:

 shopt -s nullglob function have_any() { [ $# -gt 0 ] } if have_any ./*.flac; then echo true fi 

The have_any function uses $# to count its arguments, and [ $# -gt 0 ] then checks to see if at least one argument exists. Using ./*.flac instead of *.flac in a have_any call is to avoid problems caused by files with names like --help .

0
Feb 01 '17 at 16:28
source share



All Articles