๐ Lesson 3: Files and Folders: Making, Copying, Moving and Deleting
Create, copy, rename and delete things, and the habits that keep you from deleting the wrong ones
A promise before we start
The command line has no recycle bin. When you delete something with rm, it is gone straight away, with no "are you sure?" and no undo. That sounds scary, and on your own computer it deserves respect. On your practice machine from lesson 1 it is a gift: you can learn the dangerous commands where nothing important lives. If you break something, type exit, start a fresh machine, and carry on.
Open your practice machine and follow along. Each example here was run in order, in one session, on a real Ubuntu 24.04, so if you type the same commands you will get the same results (apart from the dates).
Make folders with mkdir
mkdir means "make directory", and a directory is just a folder.
ubuntu@practice:~$ mkdir projects ubuntu@practice:~$ ls projects ubuntu@practice:~$ cd projects ubuntu@practice:~/projects$ pwd /home/ubuntu/projects ubuntu@practice:~/projects$ mkdir x/y/z mkdir: cannot create directory 'x/y/z': No such file or directory ubuntu@practice:~/projects$ mkdir -p a/b/c ubuntu@practice:~/projects$ ls a ubuntu@practice:~/projects$ ls a b
- mkdir projects makes a folder, and ls shows it. Then cd projects moves into it. The prompt shows ~/projects, because you are inside it.
- mkdir x/y/z failed: "No such file or directory". It tried to make z inside y inside x, but neither x nor y exists yet.
- mkdir -p a/b/c worked. The -p option means "make the parents too": it created a, then b inside it, then c inside that. ls a confirms b is there.
Make files with touch and echo
ubuntu@practice:~/projects$ touch notes.txt ubuntu@practice:~/projects$ echo "Buy milk" > shopping.txt ubuntu@practice:~/projects$ ls -l total 8 drwxr-xr-x 3 ubuntu ubuntu 4096 Oct 5 13:59 a -rw-r--r-- 1 ubuntu ubuntu 0 Oct 5 13:59 notes.txt -rw-r--r-- 1 ubuntu ubuntu 9 Oct 5 13:59 shopping.txt ubuntu@practice:~/projects$ cat shopping.txt Buy milk
- touch notes.txt creates an empty file. In the long listing (ls -l) its size is 0. (If the file already exists, touch just updates its timestamp, which is its other job.)
- echo "Buy milk" > shopping.txt writes the text Buy milk into a file. The > symbol means "send the output into this file instead of the screen". Lesson 11 explains it properly. One thing to know now: > replaces whatever was in the file.
- cat shopping.txt prints the file's contents. It is 9 bytes: the 8 letters of "Buy milk", plus the invisible end-of-line character.
- The a row starts with d: it is a directory, as you learned in lesson 2.
Copy with cp
ubuntu@practice:~/projects$ cp shopping.txt shopping-backup.txt ubuntu@practice:~/projects$ ls a notes.txt shopping-backup.txt shopping.txt ubuntu@practice:~/projects$ cp -r a a-copy ubuntu@practice:~/projects$ ls a a-copy notes.txt shopping-backup.txt shopping.txt ubuntu@practice:~/projects$ cp shopping.txt cp: missing destination file operand after 'shopping.txt' Try 'cp --help' for more information. ubuntu@practice:~/projects$ cp shopping.txt notes.txt ubuntu@practice:~/projects$ cat notes.txt Buy milk ubuntu@practice:~/projects$ cp -i shopping.txt notes.txt cp: overwrite 'notes.txt'? n
- cp shopping.txt shopping-backup.txt copies a file: first the original, then the name of the copy.
- To copy a folder you need -r, which stands for recursive: "the folder and everything inside it". So cp -r a a-copy copied the whole a tree.
- cp shopping.txt alone failed with "missing destination file operand". cp needs two things, a source and a destination, and the error says which one is missing. (It also helpfully suggests cp --help.)
- Look at what happened next. cp shopping.txt notes.txt copied onto an existing file called notes.txt. It did not ask. It silently replaced the empty notes.txt with a copy of shopping.txt, and cat notes.txt proves it. This is the quiet danger of cp and mv: they overwrite without warning.
- cp -i adds a safety net. The i stands for interactive: it asks "overwrite?" first, and typing n said no.
Move and rename with mv
ubuntu@practice:~/projects$ mv notes.txt ideas.txt ubuntu@practice:~/projects$ ls a a-copy ideas.txt shopping-backup.txt shopping.txt ubuntu@practice:~/projects$ mv ideas.txt a ubuntu@practice:~/projects$ ls a b ideas.txt ubuntu@practice:~/projects$ mv a/ideas.txt . ubuntu@practice:~/projects$ ls a a-copy ideas.txt shopping-backup.txt shopping.txt
Linux uses one command for both moving and renaming, because they are the same thing: giving a file a new name and place.
- mv notes.txt ideas.txt renamed the file in place.
- mv ideas.txt a moved it into the folder a. Since a is a folder, mv puts the file inside it. ls a shows ideas.txt there.
- mv a/ideas.txt . moved it back out. A single dot means "the folder I am in right now", the same dot you saw in lesson 2.
mv overwrites existing files without asking, just like cp does. It has the same safety option: mv -i.
Delete with rm and rmdir
ubuntu@practice:~/projects$ rm shopping-backup.txt ubuntu@practice:~/projects$ ls a a-copy ideas.txt shopping.txt ubuntu@practice:~/projects$ rm a rm: cannot remove 'a': Is a directory ubuntu@practice:~/projects$ rmdir a rmdir: failed to remove 'a': Directory not empty ubuntu@practice:~/projects$ rm -r a-copy ubuntu@practice:~/projects$ ls a ideas.txt shopping.txt ubuntu@practice:~/projects$ rm -i ideas.txt rm: remove regular file 'ideas.txt'? y ubuntu@practice:~/projects$ ls a shopping.txt
- rm shopping-backup.txt deleted the file. No question, no undo.
- rm a refused: "Is a directory". rm will not delete folders by default. That is a safety feature.
- rmdir a also refused: "Directory not empty". rmdir only removes empty folders, which makes it very safe.
- rm -r a-copy deleted a folder and everything inside it. The -r is the same "recursive" idea as in cp. From this point ls no longer shows a-copy.
- rm -i ideas.txt asked "remove regular file?" and y said yes. The -i makes rm ask about each file. It is slower, and wonderful when you are unsure.
โ ๏ธ You will see rm -rf in tutorials and forum posts. The -r means "folders and everything inside", and the -f means "force: do not ask and do not complain". Together they delete without a single question. Never run rm -rf on a path you have not just looked at with ls, and never paste a command you do not understand into a terminal, from any website, including this one. On a practice machine you can experiment freely. On a real machine, slow down.
Wildcards: matching many files at once
A wildcard is a character that stands for other characters, so one command can handle many files. The shell expands it into the list of matching names before the command runs.
ubuntu@practice:~/projects$ touch report1.txt report2.txt report10.txt ubuntu@practice:~/projects$ touch photo.jpg ubuntu@practice:~/projects$ ls *.txt report1.txt report10.txt report2.txt shopping.txt ubuntu@practice:~/projects$ ls report?.txt report1.txt report2.txt ubuntu@practice:~/projects$ ls report* report1.txt report10.txt report2.txt ubuntu@practice:~/projects$ rm *.jpg ubuntu@practice:~/projects$ ls a report1.txt report10.txt report2.txt shopping.txt
- * matches anything, including nothing. ls *.txt lists every file that ends in .txt.
- ? matches exactly one character. ls report?.txt found report1.txt and report2.txt, but not report10.txt, because 10 is two characters.
- ls report* matched all three.
- rm *.jpg removed photo.jpg, and only that.
The golden rule of wildcards: look before you delete. Run ls with your pattern first. If ls *.jpg lists exactly the files you mean, rm *.jpg will delete exactly those. If the list surprises you, you have just saved yourself a bad day.
Spaces in file names
Spaces separate things on the command line, so a file name with a space needs quotes:
ubuntu@practice:~/projects$ touch "my notes.txt" ubuntu@practice:~/projects$ ls a 'my notes.txt' report1.txt report10.txt report2.txt shopping.txt ubuntu@practice:~/projects$ rm my notes.txt rm: cannot remove 'my': No such file or directory rm: cannot remove 'notes.txt': No such file or directory ubuntu@practice:~/projects$ rm "my notes.txt" ubuntu@practice:~/projects$ ls a report1.txt report10.txt report2.txt shopping.txt
rm my notes.txt was read as two names, my and notes.txt, and neither exists. With quotes, rm "my notes.txt" is one name, and it worked. Notice that ls showed the name wrapped in single quotes to warn you that it contains a space. The easiest habit: avoid spaces in your own file names. Use dashes or underscores, like my-notes.txt.
Habits that keep you safe
ubuntu@practice:~/projects$ ls report*.txt report1.txt report10.txt report2.txt ubuntu@practice:~/projects$ rm -i report*.txt rm: remove regular empty file 'report1.txt'? y rm: remove regular empty file 'report10.txt'? y rm: remove regular empty file 'report2.txt'? y ubuntu@practice:~/projects$ ls a shopping.txt
- Look first, then delete. Run ls report*.txt and read the list before rm report*.txt.
- **Use -i when a wildcard is involved.** Above, rm -i report*.txt asked about every file, and y agreed.
- Check where you are. pwd before a delete. The prompt shows it too.
- Let Tab finish the names. If Tab completes it, it exists, and you did not mistype it.
- Practise here. That is what the practice machine is for.
Too many unresolved links.
๐งช Try it yourself
1. In your home folder, make a folder called garden with two folders inside it, seeds and tools, using one command. (Hint: mkdir -p accepts several names.) 2. Put a file called todo.txt in garden that says water plants. Look at it with cat. 3. Copy todo.txt to todo-old.txt, then rename the copy to archive.txt. 4. Make three files called a1.log, a2.log and a10.log. Use a wildcard so that ls shows only the first two. 5. Delete the whole garden folder, and confirm with ls that it is gone.
The cheat sheet
- mkdir NAME make a folder. mkdir -p a/b/c make all the levels.
- touch NAME make an empty file. echo "text" > NAME put text in a file (replaces what was there).
- cp SOURCE DEST copy. cp -r for folders. cp -i asks before overwriting.
- mv SOURCE DEST move or rename. mv -i asks before overwriting.
- rm NAME delete a file. rm -r NAME delete a folder and everything in it. rm -i asks first. rmdir deletes an empty folder.
- * matches anything, ? matches one character. Look with ls before you delete.
- Put quotes around names that contain spaces.
← Lesson 2 · ↑ All lessons · Lesson 4: Reading and Searching Text →