Unix How To: Using Basename Wisely

By  

At its simplest, the basename command will strip the directory structure off the front of a file reference. /usr/bin/passwd becomes passwd. /usr/local/bin/myscript becomes myscript. Easy enough. You get an extra bonus when you follow the command with a file extension. The basename command will strip that off as well. For example, you can strip off the .conf extension from a file like this:

bozon$ basename /etc/nsswitch.conf .conf
nsswitch

This little trick can help if you want to make backup copies of some files and want to change the extension rather than tack on a second one. For example:

boson$ ls *pl
findAppl   lwday.pl   parse3.pl  parse4.pl
boson$ for file in `ls *.pl`
> do
>     fname=`basename $file .pl`
>     cp $file $fname.bak
> done
boson$ ls *bak
lwday.bak   parse3.bak  parse4.bak

It helps to understand that basename doesn't really know about your files. Ask basename to remove the path from /north/pole/SantaClaus and it will respond with "SantaClaus". It's not going to come back and tell you that SantaClaus doesn't exist, spit out "file not found" or chastise you with a usage statement just because you don't have any directories that even vaguely resemble /north/pole. It just works with patterns. The basename command's only job is to chop off everything in a string up to and including the last forward slash.

That is, unless your path includes spaces! Try basename on a path that includes spaces and it will ignore everything following the first space as it takes everything prior to the space as its argument and ignores the rest:

boson$ basename /export/home/Santa Claus/gift.list
Santa

Of course, most Unix dweebs don't create directories with spaces in their names, so this isn't a problem that many of us will run across. But put your filename in quotes (e.g., "/export/home/Santa Claus/gift.lst" or "$filename") and you won't have this problem.

The basename command is also quite robotic in its processing of file extensions. Give the command .log, .txt, .conf or any in the slew of normal file extensions we use routinely and it deftly lops off the file extension along with the pesky dot. Give it some extra text and it lops off that as well:

$ basename ./final.log
final.log
$ basename ./final.log .log
final
$ basename ./final.log l.log
fina

OK, maybe that will little trick come it handy when I want to change all filenames ending in 2009. to 2010..

boson$ fname=`basename tasks2009.log 09.log`
boson$ touch ${fname}10.log
boson$ ls -l *2010*
-rw-r--r--   1 shs  staff          0 Dec 19 12:47 tasks2010.log

Ready for another year!

As much as the basename command is good at its only focus in life, it does come with a bit of a price tag. That price tag is measured in performance.

Join us:
Facebook

Twitter

Pinterest

Tumblr

LinkedIn

Google+

IT ManagementWhite Papers & Webcasts

See more White Papers | Webcasts

Answers - Powered by ITworld

Ask a Question