Opening a file with case-insensitive name

  • Follow


Let's say that I have a script that allows the user to manually type
in the file name that they want to open. It would go something like
this:

$filename = param('filename');

open FILENAME "/home/mydomain/$filename" or die;
  <do whatever...>
close FILENAME;


(Please overlook any typos above; it's just an example for the sake of
clarity, and not important.)

The question is, what if the file name is "MyFile.txt", but they type
"myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
there a way to open the file and ignore the case of the file name?

Ideally, all of the files would have been saved in lower case, then I
could just lc($filename) and be done with it. But I'm inheriting this,
and what's done is done. I could probably change all of the filenames,
but I'm hoping there's a coding option that would make it unnecessary.
0
Reply jwcarlton (271) 12/17/2009 3:15:11 AM

"Jason Carlton" <jwcarlton@gmail.com> wrote in message 
news:6ad9f15b-775f-4da3-b7b6-661712f6f9b0@k19g2000yqc.googlegroups.com...
> Let's say that I have a script that allows the user to manually type
> in the file name that they want to open. It would go something like
> this:
>
> $filename = param('filename');
>
> open FILENAME "/home/mydomain/$filename" or die;
>  <do whatever...>
> close FILENAME;
>
>
> (Please overlook any typos above; it's just an example for the sake of
> clarity, and not important.)
>
> The question is, what if the file name is "MyFile.txt", but they type
> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
> there a way to open the file and ignore the case of the file name?
>
> Ideally, all of the files would have been saved in lower case, then I
> could just lc($filename) and be done with it. But I'm inheriting this,
> and what's done is done. I could probably change all of the filenames,
> but I'm hoping there's a coding option that would make it unnecessary.

1. Get a listing of your directory contents (i.e. filenames) and store them 
in an array (or hash).
2. Do a case insensitive comparison on the variable to see if it matches any 
filename.
3. Open the file using the proper filename.

The easier way is to change your input to a controlled environment using a 
listbox selection or a drop-down entry where "you" control the file names.

Jack D.

0
Reply Jack 12/17/2009 3:41:40 AM


Jason Carlton <jwcarlton@gmail.com> writes:

> Let's say that I have a script that allows the user to manually type
> in the file name that they want to open. It would go something like
> this:
>
> $filename = param('filename');
>
> open FILENAME "/home/mydomain/$filename" or die;
>   <do whatever...>
> close FILENAME;
>
>
> (Please overlook any typos above; it's just an example for the sake of
> clarity, and not important.)
>
> The question is, what if the file name is "MyFile.txt", but they type
> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
> there a way to open the file and ignore the case of the file name?
>
> Ideally, all of the files would have been saved in lower case, then I
> could just lc($filename) and be done with it. But I'm inheriting this,
> and what's done is done. I could probably change all of the filenames,
> but I'm hoping there's a coding option that would make it unnecessary.

I would suggest to read all files in /home/mydomain/, lowercase all
entries, and match it with the lowercase version of $filename.

see perldoc -f opendir

PS. I really hope that the above code you gave doesn't come close to the
actual code.

-- 
John Bokma

Read my blog: http://johnbokma.com/
Hire me (Perl/Python): http://castleamber.com/
0
Reply John 12/17/2009 4:02:51 AM

Jason Carlton <jwcarlton@gmail.com> wrote:
>open FILENAME "/home/mydomain/$filename" or die;
>  <do whatever...>
>close FILENAME;
>
>The question is, what if the file name is "MyFile.txt", but they type
>"myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
>there a way to open the file and ignore the case of the file name?

That depends upon your operating/file system. All (newer) Windows file
systems are case-preserving, but still case-insensitive, i.e. "it would
just work". Your sample file names with the ending txt (in different
capitalization) seem to indicate that you are using some sort of
Windows.

>Ideally, all of the files would have been saved in lower case, then I
>could just lc($filename) and be done with it. But I'm inheriting this,
>and what's done is done. I could probably change all of the filenames,
>but I'm hoping there's a coding option that would make it unnecessary.

If you are on a file/operating system that is case-sensitive you could
read the directory and create a hash from it, using the normalized form
of the file name as the key and the original form as the value. 
Then you could simply say

	open FILE, $dirhash{normalize($userstring)} ......

jue
0
Reply J 12/17/2009 4:16:50 AM

> That depends upon your operating/file system. All (newer) Windows file
> systems are case-preserving, but still case-insensitive, i.e. "it would
> just work". Your sample file names with the ending txt (in different
> capitalization) seem to indicate that you are using some sort of
> Windows.

Sorry, that was my mistake. I'm running it on Linux, and didn't think
about the extension meaning anything.


> If you are on a file/operating system that is case-sensitive you could
> read the directory and create a hash from it, using the normalized form
> of the file name as the key and the original form as the value.
> Then you could simply say
>
> =A0 =A0 =A0 =A0 open FILE, $dirhash{normalize($userstring)} ......

OK, that'll work. It's not perfect, since there are about 60,000 files
to consider (which is why I don't put them in a drop menu, as Jack
suggested), but it should hold over for now. Eventually I'll set up an
Ajax system to cope with it.

Thanks, all,

Jason
0
Reply Jason 12/17/2009 4:27:24 AM

Jason Carlton wrote:
> Let's say that I have a script that allows the user to manually type
> in the file name that they want to open. It would go something like
> this:
> 
> $filename = param('filename');
> 
> open FILENAME "/home/mydomain/$filename" or die;
>   <do whatever...>
> close FILENAME;
> 
> 
> (Please overlook any typos above; it's just an example for the sake of
> clarity, and not important.)
> 
> The question is, what if the file name is "MyFile.txt", but they type
> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
> there a way to open the file and ignore the case of the file name?
> 
> Ideally, all of the files would have been saved in lower case, then I
> could just lc($filename) and be done with it. But I'm inheriting this,
> and what's done is done. I could probably change all of the filenames,
> but I'm hoping there's a coding option that would make it unnecessary.

Copy the file to a temp file with a lc($filename) setting. Do your
necessary business, and save to the original file name which you will
have saved.

my $filename = 'FiLe.Txt';

my $temp = lc ($filename);

open TMP, $temp;

# Copy file to  TMP
#Operate on TMP
# Copy $temp back to $filename
0
Reply monkeys 12/17/2009 5:02:13 AM

On Wed, 16 Dec 2009 19:15:11 -0800, Jason Carlton wrote:

> Let's say that I have a script that allows the user to manually type in
> the file name that they want to open. It would go something like this:
> 
> $filename = param('filename');
> 
> open FILENAME "/home/mydomain/$filename" or die;
>   <do whatever...>
> close FILENAME;
> 
> 
> (Please overlook any typos above; it's just an example for the sake of
> clarity, and not important.)
> 
> The question is, what if the file name is "MyFile.txt", but they type
> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is there
> a way to open the file and ignore the case of the file name?
> 
> Ideally, all of the files would have been saved in lower case, then I
> could just lc($filename) and be done with it. But I'm inheriting this,
> and what's done is done. I could probably change all of the filenames,
> but I'm hoping there's a coding option that would make it unnecessary.

untested:

my $realfilename = grep { lc($filename) eq lc($_) }
                                glob('/home/mydomain/*');

HTH,
M4
0
Reply Martijn 12/17/2009 6:39:04 AM

Martijn Lievaart wrote:
> On Wed, 16 Dec 2009 19:15:11 -0800, Jason Carlton wrote:
> 
>> Let's say that I have a script that allows the user to manually type in
>> the file name that they want to open. It would go something like this:
>>
>> $filename = param('filename');
>>
>> open FILENAME "/home/mydomain/$filename" or die;
>>   <do whatever...>
>> close FILENAME;
>>
>>
>> (Please overlook any typos above; it's just an example for the sake of
>> clarity, and not important.)
>>
>> The question is, what if the file name is "MyFile.txt", but they type
>> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is there
>> a way to open the file and ignore the case of the file name?
>>
>> Ideally, all of the files would have been saved in lower case, then I
>> could just lc($filename) and be done with it. But I'm inheriting this,
>> and what's done is done. I could probably change all of the filenames,
>> but I'm hoping there's a coding option that would make it unnecessary.
> 
> untested:
> 
> my $realfilename = grep { lc($filename) eq lc($_) }
>                                 glob('/home/mydomain/*');

That won't work as glob() returns the complete path, and grep returns 
the number of matches in scalar context, not the file name(s).  Should 
work as:

my @realfilenames = grep lc eq lc "/home/mydomain/$filename", glob 
'/home/mydomain/*';



John
-- 
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.               -- Damian Conway
0
Reply John 12/17/2009 7:36:06 AM

John Bokma wrote:
> 
> I would suggest to read all files in /home/mydomain/, lowercase all
> entries, and match it with the lowercase version of $filename.


One potential gotcha here is that lowercasing all the files in the dir could
leave you with more than 1 file with the same name.  What is the OP going
to do then I wonder?


-- 
Brian Wakem
0
Reply Brian 12/17/2009 8:39:59 AM

Brian Wakem <no@email.com> writes:

> John Bokma wrote:
>> 
>> I would suggest to read all files in /home/mydomain/, lowercase all
>> entries, and match it with the lowercase version of $filename.
>
> One potential gotcha here is that lowercasing all the files in the dir could
> leave you with more than 1 file with the same name.  What is the OP going
> to do then I wonder?

Oops, very good point.

-- 
John Bokma

Read my blog: http://johnbokma.com/
Hire me (Perl/Python): http://castleamber.com/
0
Reply John 12/18/2009 12:13:05 AM

Am 17.12.2009 08:36, schrieb John W. Krahn:
> Martijn Lievaart wrote:
>> On Wed, 16 Dec 2009 19:15:11 -0800, Jason Carlton wrote:
>>
>>> [�] The question is, what if the file name is "MyFile.txt", but they type
>>> "myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is there
>>> a way to open the file and ignore the case of the file name? [�]

> my @realfilenames = grep lc eq lc "/home/mydomain/$filename", glob
> '/home/mydomain/*';

Better
   my $filename='bLaBlA.Txt';
   (my $filepat=$filename) =~
       s{(.)}
        { local $_=$1;
          (uc ne lc)  ? "[\U$_\L$_]" :
          /[[\]{}\s]/ ? "\\$_"       : $_ # or /[[\]{}\s*?]/
        }ge;
   my @filematches=glob($filepat);
   my $mostlikely=exists $filematches[0] ? $filematches[0] : undef;

   print join(',',@filematches)." from $filepat\n"
   # BlaBla.txt from [Bb][Ll][Aa][Bb][Ll][Aa].[Tt][Xx][Tt]

The wildcards * and ? are allowed for the user.
If this is not desirable, than this chars can be added to the inner RE.

I expect that this solution is faster as the previous.

Another solution was presented from J�rgen (hash as cache).
His solution needs IHMO more time at startup for building the hash,
but the following searches should be faster.

Just guessing.

best regards & sorry for my bad english,
   Josef

0
Reply Josef 12/18/2009 1:19:22 AM

On Wed, 16 Dec 2009 20:27:24 -0800 (PST), Jason Carlton <jwcarlton@gmail.com> wrote:

>> That depends upon your operating/file system. All (newer) Windows file
>> systems are case-preserving, but still case-insensitive, i.e. "it would
>> just work". Your sample file names with the ending txt (in different
>> capitalization) seem to indicate that you are using some sort of
>> Windows.
>
>Sorry, that was my mistake. I'm running it on Linux, and didn't think
>about the extension meaning anything.
>
>
>> If you are on a file/operating system that is case-sensitive you could
>> read the directory and create a hash from it, using the normalized form
>> of the file name as the key and the original form as the value.
>> Then you could simply say
>>
>> � � � � open FILE, $dirhash{normalize($userstring)} ......
>
>OK, that'll work. It's not perfect, since there are about 60,000 files
>to consider (which is why I don't put them in a drop menu, as Jack
>suggested), but it should hold over for now. Eventually I'll set up an
>Ajax system to cope with it.
>
>Thanks, all,
>
>Jason

The question is, what if the file name is "MyFile.txt", but they type
"myfile.txt", "MYFILE.TXT", "mYfILE.txt", or something similar. Is
there a way to open the file and ignore the case of the file name?

Except that:

@dir = ('MyFile.txt', 'mYfile.Txt', 'myfilE.txT');
$input = 'myfile.txt';

There seems no choice but to conclude that there is no
file named 'myfile.txt'.

-sln
0
Reply sln 12/19/2009 5:58:20 PM

11 Replies
729 Views

(page loaded in 0.166 seconds)

Similiar Articles:


















7/21/2012 12:24:06 AM


Reply: