Shell script to check for the presence of one or more files with a specific extension?

I want to write a script to find a file with specific extension.this much i have done:

#!/bin/bash
file="/home/Savio/Dsktop/check/*.csv"
file1="/home/Savio/check/*.txt"
if [[ -f "$file" && -f "$file1" ]];
then
    echo " found."
else
    echo "not found."
fi

Where the check folder contains sub-folders. Please correct me if anything wrong is there

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

If you don’t want recursion, you can do

export DIR=/home/Savio/Dsktop/check
if ls ${DIR}/*.txt &>/dev/null && ls ${DIR}/*.csv &>/dev/null
then
    echo "Found."
else
    echo "Not found."
fi

Or, in perl:

perl -e '
    $DIR="/home/Savio/Dsktop/check";
    @a= glob "${DIR}/*.txt";
    @b= glob "${DIR}/*.csv"; 
    print  @a && @b ? "Found.n" : "Not found.n"
'

If you do want recursion, the solution proposed in the other answers will work. You can make it go faster by making find stop after the first match it finds:

export DIR=/home/Savio/Dsktop/check
CSV=$(find "$DIR" -name *.csv|head -n1)
TXT=$(find "$DIR" -name *.txt|head -n1)
[ ! -z "$CSV" ] && [ ! -z "$TXT" ] && echo Found || echo Not found

References

Method 2

bash script to check whether csv files exists and for loop all of them of exists

#!/bin/bash
# count variable to check if csv files exists in current directory
count_file=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count_file != 0 ]
then 
  for file in *.csv; do
    echo ${file##*/}
  done
fi

Method 3

The wildcard in file1 is never expanded because it’s always in quotes.

In bash, one way is to set the nullglob option so that a wildcard that matches no file expands to an empty list.

#!/bin/bash
shopt -s nullglob
csv_files=(/home/Savio/Dsktop/check/*.csv)
txt_files=(/home/Savio/check/*.txt)
if ((${#csv_files[@]} && ${#txt_files[@]}))
then
  echo " found."
else
  echo "not found."
fi

If you want to match dot files as well, set the dotglob option.

With only a POSIX shell, you need to cope with the pattern remaining unchanged if there is no match.

matches_exist () {
  [ $# -gt 1 ] || [ -e "$1" ]
}
if matches_exist /home/Savio/Dsktop/check/*.csv &&
   matches_exist /home/Savio/check/*.txt; then
  echo " found."
else
  echo "not found."
fi

Note that it looks for files regardless of their type (regular, directory, symlink, device, pipe…) while your [[ -f file ]] checks whether the file exists and is a regular file or symlink to regular file only (would exclude directories, devices…).

Method 4

find would probably work better here.

csv=$(find /home/Savio/Dsktop/check -type f -name "*.csv")
txt=$(find /home/Savio/check/ -type f -name "*.txt")

What you have will not recurse into sub-directories.

Method 5

Be aware that if [[ -f "$file" ]] will fail if $file contains more than one filename — which is likely to happen when you are selecting the file using a wildcard.

You should either check for a specific filename (without any wildcards) or use Petey T’s approach and check if the number of files found by find is greater than 0:

csv=$(find /home/Savio/Dsktop/check -type f -name "*.csv")
txt=$(find /home/Savio/check/ -type f -name "*.txt")
if [[ ( -n $csv ) -a ( -n $txt ) ]]
then
    echo "found"
else
    echo "not found"
fi


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x