Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find files using wild card in C#

Tags:

c#

file

I am trying to find files from a directory:

String[] search1 = Directory.GetFiles(voiceSource, "85267-*.wav")
                                 .Select(path => Path.GetFileName(path))
                                 .ToArray();

String[] search2 = Directory.GetFiles(voiceSource, "85267 *.wav")
                                 .Select(path => Path.GetFileName(path))
                                 .ToArray();

But in search1, it selects both 85267-s.wav and 85267 -s.wav. But I want only 85267-s.wav to be selected.

search2 is doing well.

How can I do that?

like image 544
s.k.paul Avatar asked Jan 21 '15 14:01

s.k.paul


People also ask

How do I search for a file using wildcard?

Command. When you use the wildcard character (*) at both the ends, file name containing that string will be displayed. For example, the below command will display all the files which contain the word “tmp”.

How can you use the wildcard character to search for folders?

There are two wildcard characters: asterisk (*) and question mark (?). Asterisk (*) - Use the asterisk as a substitute for zero or more characters. e.g., friend* will locate all files and folders that begin with friend. Question mark (?)- Use the question mark as a substitute for a single character in a file name.

How do you use a wildcard in a filename?

When you have a number of files named in series (for example, chap1 to chap12) or filenames with common characters (like aegis, aeon, and aerie), you can use wildcards (also called metacharacters) to specify many files at once. These special characters are * (asterisk), ? (question mark), and [ ] (square brackets).

Can you use wildcards with MV?

Can be used by: Standard wildcards are used by nearly any command (including mv, cp, rm and many others). this can represent any single character. If you specified something at the command line like "hd?" GNU/Linux would look for hda, hdb, hdc and every other letter/number between a-z, 0-9.


2 Answers

The behaviour you are experiencing is because of short file name. Since you will get 85267-~1.WAV for 85267 -s.wav and since that matches your wild card "85267-*.wav" you get both files back.

The is explained in Directory.GetFiles Method (String, String)

Because this method checks against file names with both the 8.3 file name format and the long file name format, a search pattern similar to "1.txt" may return unexpected file names. For example, using a search pattern of "1.txt" will return "longfilename.txt" because the equivalent 8.3 file name format would be "longf~1.txt".

For workaround you can use Directory.EnumerateFiles to first select both files matching your criteria and then compare the actual(long) file name part using StartsWith. Remember EnumerateFiles does lazy evaluation.

String[] search1 = Directory.EnumerateFiles(@"C:\test", "85267-*.wav")
                         .Where(file => Path.GetFileName(file).StartsWith("85267-"))
                         .Select(path => Path.GetFileName(path))
                         .ToArray();
like image 113
Habib Avatar answered Oct 08 '22 03:10

Habib


Yes, this is a side-effect of the MS-Dos 8.3 short name support that's still turned on today on most file systems. Something you can see with the DIR /X command, it displays those short names. On my machine:

C:\temp>dir /x *.wav

01/21/2015  09:11 AM                 6 85267-~1.WAV 85267 -s.wav
01/21/2015  09:11 AM                 6              85267-s.wav
               2 File(s)             12 bytes
               0 Dir(s)  235,121,160,192 bytes free

Note how the short name for "85267 -s" is missing the space. It is not a valid character in a short name. What's left over now also matches your wildcard.

That's not where the trouble ends with those short names, A wildcard like *.wav will also match a file like foobar.wavx, a completely different file type.

Short-name generation is, frankly, a relic from the previous century that ought to be turned off today. But that is not typically anything you can control yourself. You have to deal with these accidental matches and double-check what you get back. With a Regex for example.

like image 38
Hans Passant Avatar answered Oct 08 '22 02:10

Hans Passant