-   Linux - General (
-   -   same filenames in a directory with different case (

venkat_eg 08-15-2009 01:36 AM

same filenames in a directory with different case
sir, my directory having files with same names but letter case is different. when i copy the files, i want to over write the files already existing with the same name. here i want to ignore the case sensitive of the letter.

catkin 08-15-2009 03:53 AM

Hello Venkat :)

On *n*x computers, unlike Windows, file names which differ in case are different; foo, Foo, fOO etc. are different mames. So copying Foo into a directory will not replace foo.

If it's possible, the easiest for you would be to change all the filenames to the same case.

Here's a script from the Advanced Bash Scripting Guide that says it will do it

#  Changes every filename in working directory to all lowercase.
#  Inspired by a script of John Dubois,
#+ which was translated into Bash by Chet Ramey,
#+ and considerably simplified by the author of the ABS Guide.

for filename in *                # Traverse all files in directory.
  fname=`basename $filename`
  n=`echo $fname | tr A-Z a-z`  # Change name to lowercase.
  if [ "$fname" != "$n" ]      # Rename only files not already lowercase.
    mv $fname $n

exit $?

I'm a little worried by some aspects of this script like it renames directories as well as files (maybe that's OK) and if you start with Foo, FOO and foo then you will end up with only one of them or an error depending on how your mv works.

For the script-sperts: I don't think fname=`basename $filename` does anything useful, it's functionally equivalent to fname=filename.

Working on a script and will post later ...


Oops! The Advanced Bash Scripting Guide already noted defects in the above scripts and gives this improvement

# The above script will not work on filenames containing blanks or newlines.
# Stephane Chazelas therefore suggests the following alternative:

for filename in *    # Not necessary to use basename,
                    # since "*" won't return any file containing "/".
do n=`echo "$filename/" | tr '[:upper:]' '[:lower:]'`
#                            POSIX char set notation.
#                    Slash added so that trailing newlines are not
#                    removed by command substitution.
  # Variable substitution:
  n=${n%/}          # Removes trailing slash, added above, from filename.
  [[ $filename == $n ]] || mv "$filename" "$n"
                    # Checks if filename already lowercase.

exit $?

If you start with Foo, FOO and foo then this improved script still means you will end up with only one of them or an error depending on how your mv works.



catkin 08-15-2009 04:16 AM

This one prints error messages when foo and FOO both exist in the current directory


# Rename all files in current directory to lowercase names.
# Assumes no control characters in the file names.
# OK with whitespace in the file names.

shopt -s extglob
shopt -s nocaseglob

for file in *
        if [[ "$(echo "$file"?([[:ctrl:]]))" = "$file" ]];then
                newfile="$( echo -n "$file" | /usr/bin/tr '[:upper:]' '[:lower:]' )"
                if [[ "$newfile" != "$file" ]]; then
                        echo /bin/mv "$file" "$newfile"
                echo "These files generate duplicate file names when folded to lower case: " $file?([[:ctrl:]])

All times are GMT -5. The time now is 12:06 PM.