Tuesday, June 07, 2005

More on "basename" command

Previously I have only told that basename strips off extra part from a filename.And i showed that its stripping off last extentions of test.sh.sh and making it test.sh.But its not the whole picture of basename.Basename can also stip off from the beginning.In fact it just returns the filename.Umm...I can say it tries its best to return the filename only.See the following example.

$ basename /GrandDad/Dad/Son/GrandChild.txt
GrandChild.txt
$


The basename command analyzes the string and takes out the pieces it estimates to be the directory path. Basically, it leaves the last piece of the string that doesn't contain a slash (/). It also removes any trailing slash in order to identify the base portion of the name. In the following listing, the final slash is removed before evaluating the string and returning the word file as the "base" for the string.

$ basename /GrandDad/Dad/Son/
Son
$



The basename utility is very useful for situations in which files are replicated across multiple directories. In a hypothetical system, a series of directories contain the current versions of documents, the newest versions of documents to replace the current versions, and two earlier versions of the same documents where they've been replaced. Assuming that the directories are named new, current, old and oldest, a process is needed to check the names of all the new documents in the new directory. Any documents with the same name in the old directory are moved to the oldest directory, any documents with the same name in the current directory are moved to the old directory, and finally the new documents are moved to the current directory. Using a for name loop, the code to do this would look as follows (the listing is numbered for explanatory purposes):

1 for name in /docs/new/*
2 do
3 fname=`basename $name`
4 if [ -f /docs/old/$fname ]
5 then
6 mv /docs/old/$fname /docs/oldest/$fname
7 fi
8 if [ -f /docs/current $fname ]
9 then
10 mv /docs/current/$fname /docs/old/$fname
11 fi
12 mv /docs/new/$fname /docs/current/$fname
13 done


The basename command is used to extract just the filename portion into the variable fname. From there, the $fname variable is used to construct various tests and copies. The for name loop at line 1 sets the variable $name to each filename that matches /docs/new/* and then executes the logic between lines 2 and 13. At line 3 basename is used to extract just the file portion of the name into the variable $fname. Once the base portion of the filename is identified, a series of tests and moves can be executed. At line 4 the logic tests to see if a file of the same name exists in the /docs/old directory. If it does, it's moved to /docs/oldest at line 6. This is repeated for the /docs/current and docs/old directories at lines 8 through 11. Finally, at line 12 the file in /docs/new is moved into /docs/current. The logic at line 12 doesn't bother testing for the existence of the file because the for name logic started at line 1 has established that something does exists in /docs/new.

This logic assumes that the /docs/new directory will only contain files that are to be installed in /docs/current and will not contain subdirectories.

Removing extensions

I have discussed that already.This is nothing but to brush up knowledge.The basename utility also allows the extension or suffix to be stripped from a file basename. The extension to be stripped is added after the file path. In the following example, .txt is added after the filename. The return from basename is the single word file:

$ basename /this/is/a/file.txt .txt
file
$

To illustrate this hypothetically, assume that documents in the master directory are copied to a holding directory for comments. Any comments are written to a file with the extension .comment. For example, a document named proposal.doc might have a corresponding file named proposal.comment containing any comments on the document.

A process to gather up the comments has two jobs to do. First it must check that comments have been entered for a document and remove the copy of the document and the comments. Its second task is to raise an alert about any documents that have not been commented on. A process to do this is illustrated in the following numbered listing:

1 for name in /docs/for_comment/*.doc
2 do
3 bname=`basename $name .doc`
4 cname=${bname}.comment
5 dname=${bname}.doc
6 if [ -f /docs/for_comment/$cname ]
7 then
8 mv /docs/for_comment/$cname /docs/master/$cname
9 rm -f /docs/for_comment/$dname
9 else
10 echo "No comments received for $dname"
11 fi
12 done

At line 1, the name of every doc file in /docs/for_comment is extracted into the $name variable. At line 2, the filename is stripped of both the directory information, and the file extension. At lines 4 and 5, this root is built up again into two variables containing filename.doc and filename.comment. At line 6, a test is made for a file with a .comment extension. If one is found, the comment file is moved back into the master directory, and the temporary version of the document that was placed in /docs/for_comment is removed. If no comment file is found, a message is displayed on the console that comments are missing for the document. This is repeated for each doc file in /docs/for_comment.

Labels:

0 Comments:

Post a Comment

<< Home