Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


File and Directory Questions

In this section, I will look at some questions about files and directories. These questions include issues with specific commands and examples that illustrate the usage of commands to solve particular problems.

How do I determine the full pathname of a directory?

Shell scripts that work with directories often need to determine the full pathname of a directory to perform the correct operations on these directories.

You can determine the full pathname of a directory by using the cd and pwd commands:

FULLPATH=`(cd dir ; pwd)`

Here dir is the name of a directory. This command changes directories to the specified directory, dir, and then displays the full pathname of the directory using the pwd command. Because command substitution is used, the full pathname is assigned to the variable FULLPATH.

Because the cd command changes the working directory of the current shell, you execute it in a subshell. Thus the working directory of the shell script is unchanged.

How do I determine the full pathname of a file?

Determining the full pathname of a file is slightly harder than determining the full pathname of a directory. You need to use the dirname and basename commands in conjunction with the cd and pwd commands to determine the full pathname of a file:

CURDIR=`pwd`
cd `dirname file`
FULLPATH="`pwd`/`basename file`"
cd $CURDIR

Here file is the name of a file whose full pathname you want to determine. First you save the current path of the current directory in the variable CURDIR. Next you change to the directory containing the specified file, file.

Then you join the output of the pwd command and the name of the file determined using the basename command to get the full pathname. This value gets stored in the variable FULLPATH. Finally you change back to the original directory.

How can locate a particular file?

The structure of the UNIX directory tree sometimes makes locating files and commands difficult. To locate a file, often you need to search through a directory and all its subdirectories. The easiest way to do this is to use the find command:

find dir -name file -print

Here dir is the name of a directory where find should start its search, and file is the name of the file it should look for.

The name option of the find command also works with the standard filename substitution operators covered in Chapter 8. For example, the command

find dir -name "*txt" -print

displays a list of all the files in the directory dir and all its subdirectories that end with the string txt.

How can I grep for a string in every file in a directory?

When you work on a large project involving many files, remembering the contents of the individual files becomes difficult. It is much easier to look through all the files for a particular piece of information.

You can use the find command in conjunction with the xargs command to look for a particular string in every file contained within a directory and all its subdirectories:

find dir -type f -print | xargs grep "string"

Here dir is the name of a directory in which to start searching, and string is the string to look for. Here you specify the -type option to the find command so that only regular files are searched for the string.

How do I remove all the files in a directory matching a particular name?

Some editors and programs create large numbers of temporary files. Often you need to clean up after these programs, to prevent your hard drive from filling up.

To generate the list of files to delete, you can use the find command. Most of the time you can combine the find command with the xargs command, but in this case the filenames can contain one or more spaces. Spaces can confuse the xargs command, so you need to use a for loop instead:

OLDIFS="$IFS"
IFS='
'
for FILE in `find . -type f -name "*string*" -print`
do
    rm "$FILE"
done
IFS="$OLDIFS"

Here string is a string that should be part of the name of each file you want to delete. So that the for loop is set to the correct value of FILE in each iteration, IFS needs to be set to the newline character.

If you do not change IFS, filenames that contain spaces will be interpreted as multiple files instead of as a single file.

What command can I use to rename all the *.aaa files to *.bbb files?

In DOS and Windows, you can rename all the *.aaa files in a directory to *.bbb by using the rename command as follows:

rename *.aaa *.bbb

In UNIX you can use the mv command to rename files, but you cannot use it to rename more than one file at the same time. To do this, you need to use a for loop:

OLDSUFFIX=aaa
NEWSUFFIX=bbb
for FILE in *."$OLDSUFFIX"
do
    NEWNAME=`echo "$FILE" | sed -e "s/${OLDSUFFIX}\$/$NEWSUFFIX/"`
    mv "$FILE" "$NEWNAME"
done

Here you generate a list of all the files in the current directory that end with the value of the variable OLDSUFFIX. Then you use sed to modify the name of each file by removing the value of OLDSUFFIX from the filename and replacing it with the value of NEWSUFFIX. You use the $ character in your sed expression to anchor the suffix in OLDSUFFIX to the end of the line. You do this to make sure the pattern that is replaced is really a filename suffix.

After you have a new name, you rename the file from its original name, stored in FILE, to the new name stored, stored in NEWNAME.

To prevent a potential loss of data, you might need to modify this loop to specify the -i option to the mv command. For example, if the files 1.aaa and 1.bbb exist prior to executing this loop, after the loops exits, the original version of 1.aaa will be overwritten when 1.bbb is renamed as 1.aaa. If mv -i is used, you will be prompted before 1.bbb is renamed:

mv: overwrite 1.aaa (yes/no)?

You can answer no to avoid losing the information in this file. The actual prompt produced by mv might be different on your version of UNIX.


Previous Table of Contents Next