December 23, 2009, 12:56 PM — 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.
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.




















