Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Opening a file with case-insensitive name

0 views
Skip to first unread message

Jason Carlton

unread,
Dec 16, 2009, 10:15:11 PM12/16/09
to
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.

Jack

unread,
Dec 16, 2009, 10:41:40 PM12/16/09
to
"Jason Carlton" <jwca...@gmail.com> wrote in message
news:6ad9f15b-775f-4da3...@k19g2000yqc.googlegroups.com...

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.

John Bokma

unread,
Dec 16, 2009, 11:02:51 PM12/16/09
to
Jason Carlton <jwca...@gmail.com> writes:

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/

J�rgen Exner

unread,
Dec 16, 2009, 11:16:50 PM12/16/09
to
Jason Carlton <jwca...@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

Jason Carlton

unread,
Dec 16, 2009, 11:27:24 PM12/16/09
to
> 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

monkeys paw

unread,
Dec 17, 2009, 12:02:13 AM12/17/09
to

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

Martijn Lievaart

unread,
Dec 17, 2009, 1:39:04 AM12/17/09
to

untested:

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

HTH,
M4

John W. Krahn

unread,
Dec 17, 2009, 2:36:06 AM12/17/09
to

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

Message has been deleted

John Bokma

unread,
Dec 17, 2009, 7:13:05 PM12/17/09
to
Brian Wakem <n...@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.

Josef

unread,
Dec 17, 2009, 8:19:22 PM12/17/09
to
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

s...@netherlands.com

unread,
Dec 19, 2009, 12:58:20 PM12/19/09
to

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 new messages