0

I am recovering files from a broken disk but it's sorting them randomly in folders named dir1, dir2,...

I am trying to create a script that sorts them in folders according their extension

The problem is that there are some files with no extension and the script is creating a folder for each of these files when it should be ignoring them.

Here is my code:

#!/bin/sh

BASEPATH=/media/potato/toshiba/WD320
SOURCEPATH=$BASEPATH/recovered/*
DESTINATIONPATH=$BASEPATH/sorted
DELIMITER="."

function iterateFolder {
    for filename in $1; do
            #checks if file is actually a folder
            #if it is a folder call this function again
            if [ -d $filename ] ;
            then
                    echo "iterating folder $filename"
                    iterateFolder "$filename/*"
            else            
                    #checks if the name of the file has extension ( actually it checks if there is "." in the name of the file)
                    #if it doesn't, ignore the file

                    if [ -z "${filename##*$DELIMITER*}" ] ;
                    then
                            fileExtension="${filename##*.}"
                            #checks if already exists a folder in the destination folder with the name of the extension
                            if [ ! -d "$DESTINATIONPATH/$fileExtension" ] ;
                            then
                                    newDir="$DESTINATIONPATH/$fileExtension"
                                    echo "creating folder $newDir"
                                    mkdir -p $newDir
                            fi
                    fi
            fi
    done
}
iterafteFolder "$SOURCEPATH"
  • Won't help much, but my standard practice is that scripts MUST support --debug, --verbose, --help and --nooperation switches. I use a template to make this easier. – waltinator Nov 8 at 23:14
1

Your mistake is in the line if [ -z "${filename##*$DELIMITER*}" ] ;. The ## operator has to make a complete match to remove anything from the string; therefore, if the filename doesn't have a . in it, it will be unmodified by ##, thus causing the if condition to succeed. We can test this in a shell:

$ foo=bar
$ if [ -z "${foo##*.*}" ]; then echo 'Yes'; fi
Yes
$

The more traditional way to do this would be to use [[ and a =~ qualifier to check against a regex. For example:

$ if [[ $foo =~ *.* ]]; then echo 'Yes'; else echo 'No'; fi
No
$

You can learn more about [[ here. The gist of it is that [[ is more powerful and flexible at the cost of being a system binary and not a shell builtin, thus incurring a theoretical performance penalty due to starting up a new process. The penalty is pretty much negligible so you shouldn't worry about it.

New contributor
PolarBearDog is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

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.