Hey, Scripting Guy! How can I extract just the file name from the full path to the file?
— SD
Hey, SD. As you might know, Ted Williams was the last major league baseball player to bat .400 for an entire season. Coming into the final day of the year, Williams was actually hitting something like .3997 which, when rounded up, would give him an official batting average of .400. The manager of the Red Sox offered to let Williams sit out the final doubleheader, enabling him to ensure his place in baseball history. But Ted Williams refused to take the easy way out: not only did he want to play, but he wanted to reach .400 legitimately, not due to some mathematical hocus-pocus like rounding up.
So what happened? Williams went 6-for-8 in the final doubleheader, hit .406 for the season, and punched his ticket to the Baseball Hall of Fame. And all because he refused to take the easy way out. No doubt there’s a lesson in there for all of us.
As it turns out, the Scripting Guys faced a similar dilemma when it came time to answer your question. This is actually a fairly easy question to answer; in fact, the solution requires just three lines of code. That’s fine, but it doesn’t really sound like enough information to build an entire column out of. So, will the Scripting Guys be like Ted Williams and refuse to take the easy way out? Will they go above and beyond the call of duty and write a long and thoughtful column on a more complicated subject? Will they do the right thing?
You’ve got to be kidding, right? Here’s what we came up with instead:
Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFile = objFSO.GetFile(“C:\Scripts\Test.txt”) Wscript.Echo “File name: ” & objFSO.GetFileName(objFile)
So why is this question is so easy to answer? Because the FileSystemObject has several methods for extracting the individual pieces of a file path, including one method – GetFileName – that can grab just the file name for you. To do that we simply create an instance of the Scripting.FileSystemObject, then use the GetFile method to bind to the file in question (in this case, C:\Scripts\Test.txt). After that we call the GetFileName method, passing the object reference to C:\Scripts\Test.txt as the sole parameter to that method:
Wscript.Echo “File name: ” & objFSO.GetFileName(objFile)
And what do we get back? We get back the name of the file, just like you were hoping to:
test.txt
The end.
Actually, that’s a good point: there’s no doubt that Ted Williams would have done more than simply type three lines of code. OK, how about this? Here’s a revised script that shows some of the other items that the FileSystemObject can extract from a file path:
Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFile = objFSO.GetFile(“C:\Scripts\Test.txt”)Wscript.Echo “Absolute path: ” & objFSO.GetAbsolutePathName(objFile) Wscript.Echo “Parent folder: ” & objFSO.GetParentFolderName(objFile) Wscript.Echo “File name: ” & objFSO.GetFileName(objFile) Wscript.Echo “Base name: ” & objFSO.GetBaseName(objFile) Wscript.Echo “Extension name: ” & objFSO.GetExtensionName(objFile)
And here’s what we get back:
Absolute path: C:\scripts\test.txt Parent folder: C:\scripts File name: test.txt Base name: test Extension name: txt
Better? Admittedly it’s not quite the same thing as going 6-for-8 in a doubleheader. But we like to think of it as being the scripting equivalent.
Incidentally, this approach works with UNC paths as well as with local file paths. Suppose we have a file with the UNC path \\atl-fs-01\Public\Test.txt. If we run GetFileName against that file we’ll get back the following:
Absolute path: \\atl-fs-01\public\test.txt Parent folder: \\atl-fs-01\public File name: test.txt Base name: test Extension name: txt
Nice.
The only catch to all this is that the file must exist; otherwise you’ll get a “File not found” error. But suppose you have a series of file paths that don’t exist. What do you do then? Give up?
Come on: would Ted Williams give up? Of course not. Instead, he’d write a script like this:
strName = “C:\Scripts\Test.txt” arrNames = Split(strName, “\”) intIndex = Ubound(arrNames) Wscript.Echo “File name: ” & arrNames(intIndex)
What we’re doing here is taking a file path (C:\Scripts\Test.txt) and stashing that path in a variable named strName. We then use the VBScript Split function to chop that file into an array, splitting the path on the \ character:
arrNames = Split(strName, “\”)
When we do that we end up with an array consisting of the following elements:
• |
C: |
• |
Scripts |
• |
Test.txt |
Does that help us? You bet it does. As you can see, the very last element in the array just happens to be our file name. To retrieve that value we need to first use the Ubound function to determine the index number of that item:
intIndex = Ubound(arrNames)
And then, with the index number in hand, we can echo back the file name:
Wscript.Echo “File name: ” & arrNames(intIndex)
It’s a tiny bit more complicated than using the FileSystemObject, and it gets even more complicated if we wanted to tease out, say, the file extension or the parent folder. But if all we want is the file name it’s not so bad.
Does that answer your question, SD? If it does, well, we hope you’ll remember the Scripting Guys when it comes time to elect inductees to the Scripting Hall of Fame. And if it doesn’t, well, maybe you could still vote for us when it comes time to elect inductees to the Scripting Hall of Fame. After all, we’re pretty sure that’s where Ted Williams would have preferred to be immortalized. Too bad he had to settle for the Baseball Hall of Fame
0 comments