Work with Files and Directories – Take Control of the Mac Command Line with Terminal, 3rd Edition

Work with Files and Directories

Much of what you’ll need to do on the command line involves working with files in some way—creating, deleting, copying, renaming, and moving them. This chapter covers the essentials of interacting with files and directories.

Create a File

I want to begin by mentioning a curious command called touch that serves two interesting functions:

  • When supplied with the name a nonexistent file as an argument, touch creates an empty file.

  • When supplied with the name of an existing file or folder as an argument, touch updates its modification date to the current date and time, marking it as modified.

Try entering the following command:

touch file1

Now use ls -l to list the contents of your current directory. You’ll see file1 in the list. This file that you’ve just created is completely empty. It doesn’t have an extension, or a type, or any contents. It’s just a marker, though you could use a text editor, for example, to add to it.

Why would you do this? There are occasionally situations in which a program behaves differently based solely on the existence of a file with a certain name in a certain place. What’s in the file doesn’t matter—just that it’s there. Using touch is the quickest way to create such a file.

But for the purposes of this book, the reason to know about touch is so you can create files for your own experiments. Since you’re creating the files, you can rename, move, copy, and delete them without worrying about causing damage. So try creating a few files right now with touch.

As for the other use of touch—marking a file as modified—you might do this if, for example, the program that saved it failed to update its modification date for some reason and you want to make sure your backup software notices the new version. You use exactly the same syntax, supplying the name of the existing file:

touch file1

When applied to an existing file, touch doesn’t affect its contents at all, only its modification date.

Create a Directory

To create a directory (which, of course, appears in the Finder as a folder), use the mkdir (“make directory”) command. To make a directory called apples, you’d enter the following:

mkdir apples

That’s it! A few other potentially useful things to be aware of:

  • You can create a new directory in some other location than your current one (for example, you could enter mkdir ~/Documents/apples).

  • If you want to create a hierarchy of directories—for example, you want to create a directory called oranges inside ~/Documents/fruit/citrus/ and the fruit and citrus directories don’t already exist—add the -p flag (for example: mkdir -p ~/Documents/fruit/citrus/oranges).

  • Spaces, apostrophes, and quotation marks in directory names must be escaped (see Spaces in Paths).

Copy a File or Directory

To duplicate a file (in the same location or another location), use the cp (“copy”) command. It takes two arguments: the first is the file you want to copy, and the second is the destination for the copy. For example, if you’re in your home directory (~) and want to make a copy of the file file1 and put it in the Documents directory, you can do it like this:

cp file1 Documents

The location of the file you’re copying, and the location you’re copying it to, can be expressed as relative or absolute paths. For instance:

cp file1 /Users/Shared

cp /Users/jk/Documents/file1 /Users/Shared

cp file1 ..

cp ../../file1 /Users/Shared

If you want to duplicate a file and keep the duplicate in the same directory, enter the name you want the duplicate to have:

cp file1 file2

Likewise, if you want to copy the file to another location and give the copy a new name, specify the new name in addition to the destination:

cp file1 Documents/file2

Avoid Overwriting Files When Copying

Look back at the first example above:

cp file1 Documents

Anything strike you as suspicious about that? We know there’s a file called file1 and a directory called Documents in the current directory, so will this command copy file1 into Documents or make a copy in the current directory and name the copy Documents (potentially overwriting the existing directory)? The answer is: cp is smart. The command assumes that if the second argument is the name of an existing directory, you want to copy the file to that directory; otherwise, it copies the file in the current directory, giving it the name of the second argument. It won’t overwrite a directory with a file.

But, in fact, cp is not quite as smart as you might like. Let’s say there’s already a file in Documents that’s called file1. When you enter cp file1 Documents, the command happily overwrites the file that’s already in Documents without any warning! The same goes for duplicating files in the same directory. If the current directory contains files file1 and file2, entering cp file1 file2 overwrites the old file2 file with a copy of file1!

Fortunately, you can turn on an optional warning that appears if you’re about to overwrite an existing file, using the -i (“interactive”) flag. So if you enter cp -i file1 Documents and there’s already a file1 in Documents, you’ll see:

overwrite Documents/file1? (y/n [n])

Then enter y or n to allow or disallow the move. “No” is the default.

Because the -i flag can keep you out of trouble, I suggest you always use it with the cp command. Or, for an easier approach, set up an alias that does this for you automatically; see Create Aliases.

Copy Multiple Files

You can copy more than one file at a time, simply by listing all the files you want to copy, followed by the (single) destination where all the copies will go. For example, to copy files named file1, file2, and file3 into /Users/Shared, enter this:

cp file1 file2 file3 /Users/Shared

Copy a Directory

You can use the cp command to copy a directory, but you must add the -r (“recursive”) flag. For instance, given a directory named apples, this command would produce an error message:

cp apples ~/Documents

The correct way to enter the command is as follows:

cp -r apples ~/Documents

Move or Rename a File or Directory

If you want to move a file from one location to another, you use the mv (“move”) command. This command takes two arguments: the first is what you want to move, and the second is where you want to move it.

For example, if you’re in ~ and you want to move file1 from the current directory to the Documents directory, you can do it like this:

mv file1 Documents

As with cp, the location of the file you’re moving, and the location you’re moving it to, can be relative or absolute paths. Some examples:

mv file1 /Users/Shared

mv /Users/jk/Documents/file1 /Users/Shared

mv file1 ..

mv ../../file1 /Users/Shared

If you want to rename a file, you also use the mv (move) command. Weird as it may sound, mv does double duty. When you’re renaming a file, the second argument is the new name. For example, to rename the file file1 to file2, leaving it in the same location, enter this:

mv file1 file2

Avoid Overwriting Files When Moving

The mv command works the same way as cp when it comes to overwriting files: it won’t overwrite a directory with a file of the same name, but it will happily overwrite files unless you tell it not to do so.

Fortunately, mv supports the same optional -i flag as cp to warn you when you’re about to overwrite a file. So if you enter mv -i file1 Documents and there’s already a file1 in Documents, you’ll see this:

overwrite Documents/file1? (y/n [n])

You can then enter y or n to allow or disallow the move. Again, “no” is the default.

As with cp, the -i flag is such a good idea that I suggest you get in the habit of using it every single time you enter mv. Alternatively, you can set up an alias that does this for you automatically; see Create Aliases.

Move and Rename in One Go

Since mv can move and rename files, you may be wondering if you can do both operations at the same time. Indeed you can. All it takes is entering the new name after the new location. For instance, if you have a file named file1 and you want to move it into the Documents directory where it will then be called file2, you can do it like this:

mv file1 Documents/file2

Move Multiple Files

You can move several files at once, by listing all the files you want to move, followed by the (single) destination to which they’ll all go. For example, to move files named file1, file2, and file3 into /Users/Shared, enter this:

mv file1 file2 file3 /Users/Shared

Delete a File

To delete a file, use rm (“remove”), followed by the filename:

rm file1

You can delete multiple files at once by listing them each separately:

rm file1 file2 file3 file4

And, of course, you can use wildcards:

rm file*

Needless to say, you should be extra careful when using the * wildcard with the rm command!

Delete a Directory

Just as you can delete a folder in the Finder by dragging it to the Trash, you can delete a directory on the command line with the rmdir (“remove directory”) command.

To delete a directory named apples, you can enter this:

rmdir apples

As with rm, you can delete multiple directories at the same time:

rmdir pomegranates pomelos

rmdir pome*

This command works only on empty directories. (A directory can have invisible files created by macOS; don’t assume it’s empty just because you didn’t put anything there.) If you run rmdir on a non-empty directory, you get this error message:

rmdir: apples: Directory not empty

This is a safety feature designed to prevent accidental deletions. If you’re sure you want to delete a directory and its contents (including subdirectories), use the rm command (instead of rmdir) with the -r (recursive) flag:

rm -r apples