5

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

2

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

| improve this answer | |
2

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...).

| improve this answer | |
1

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.

| improve this answer | |
1

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
| improve this answer | |
  • 1
    Actually, wildcards aren't expanded into globs inside [[ see Greg's wiki – Joseph R. Aug 20 '13 at 17:02
  • To make your if condition POSIX-compliant, you can do if [ ! -z $csv ] && [ ! -z $txt ]... – Joseph R. Aug 20 '13 at 17:23
  • 1
    Wildcards aren't expanded inside [[ but the wildcard will be expanded when file and file1 are set. – doneal24 Aug 20 '13 at 17:42
  • @DougO'Neal Right you are. My bad... – Joseph R. Aug 20 '13 at 17:46
1

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 
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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