UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 45.17 Making a for Loop with Multiple Variables Chapter 45
Shell Programming for the Initiated
Next: 45.19 A while Loop with Several Loop Control Commands
 

45.18 Using basename and dirname

basename
dirname
Almost every UNIX command can use relative and absolute pathnames (14.2) to find a file or directory. There are times you'll need part of a pathname - the head (everything before the last slash) or the tail (the name after the last slash). The utilities basename and dirname, available on most UNIX systems (and on the CD-ROM) handle that.

45.18.1 Introduction to basename and dirname

The basename command strips any "path" name components from a filename, leaving you with a "pure" filename. For example:

% basename /usr/bin/gigiplot
gigiplot
% basename /home/mikel/bin/bvurns.sh
bvurns.sh

basename can also strip a suffix from a filename. For example:

% basename /home/mikel/bin/bvurns.sh .sh
bvurns

The dirname command strips the filename itself, giving you the "directory" part of the pathname:

% dirname /usr/bin/screenblank
/usr/bin
% dirname local
.

If you give dirname a "pure" filename (i.e., a filename with no path, as in the second example), it tells you that the directory is . (the current directory).

NOTE: dirname and basename have a bug in many System V implementations. They don't recognize the second argument as a filename suffix to strip. Here's a good test:

% basename 0.foo .foo

If the answer is 0, your basename implementation is good. If the answer is 0.foo, the implementation is bad. If basename doesn't work, dirname won't, either.

45.18.2 Use with Loops

Here's an example of basename and dirname. There's a directory tree with some very large files - over 100,000 characters. You want to find those files, run split (35.9) on them, and add huge. to the start of the original filename. By default, split names the file chunks xaa, xab, xac, and so on; you want to use the original filename and a dot (.) instead of x:



|| exit 



for path in `find /home/you -type f -size +100000c -print`
do

    cd `dirname $path` || exit
    filename=`basename $path`
    split $filename $filename.
    mv -i $filename huge.$filename
done

The find command will output pathnames like these:

/home/you/somefile
/home/you/subdir/anotherfile

(The absolute pathnames are important here. The cd would fail on the second pass of the loop if you use relative pathnames.) In the loop, the cd command uses dirname to go to the directory where the file is. The filename variable, with the output of basename, is used several places - twice on the split command line.

If that gives the error command line too long, replace the first lines with the two lines below. This makes a redirected-input loop (45.22):

find /home/you -type f -size +100000c -print |
while read path

- JP, ML


Previous: 45.17 Making a for Loop with Multiple Variables UNIX Power ToolsNext: 45.19 A while Loop with Several Loop Control Commands
45.17 Making a for Loop with Multiple Variables Book Index45.19 A while Loop with Several Loop Control Commands

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System