Skip to content
elephantoo

Working with files & directories

Lesson 5 of 31 15 min read

mkdir, touch, cp, mv, rm, wildcards and brace expansion, and how to avoid deleting the wrong thing.


Now you'll create, copy, move, rename and delete files and directories. These commands are simple, but some of them are irreversible: Linux has no recycle bin on the command line. Learn the safe habits from day one.

Creating directories: mkdir#

Terminal
mkdir work
cd work
mkdir reports images
mkdir -p projects/2026/q4/drafts     # -p creates missing parents, and doesn't fail if it exists
ls -R projects
Output
projects:
2026

projects/2026:
q4

projects/2026/q4:
drafts

projects/2026/q4/drafts:

Creating files: touch and redirection#

touch creates an empty file, or updates the timestamp of an existing one:

Terminal
touch notes.txt
echo "first line" > hello.txt          # create/overwrite with content
echo "second line" >> hello.txt        # append
cat hello.txt
Output
first line
second line

> overwrites without asking. >> appends. You'll learn redirection properly in Pipes & redirection. To avoid accidental overwrites, set -o noclobber makes > refuse to replace existing files.

Copying: cp#

Terminal
cp hello.txt hello-backup.txt          # copy a file
cp hello.txt notes.txt reports/        # copy several files into a directory
cp -r projects projects-copy           # copy a directory recursively
ls reports
Output
hello.txt  notes.txt
OptionEffect
-r / -Rrecursive: needed for directories
-iask before overwriting
-nnever overwrite
-vverbose: show each file copied
-aarchive mode: recursive, keeps permissions, owners, timestamps and links. Ideal for backups
-ucopy only when the source is newer

Watch the trailing-directory rule. If the destination is an existing directory, files go inside it. Otherwise the destination is the new name.

Moving and renaming: mv#

Linux has no separate rename command for single files. Renaming is moving:

Terminal
mv hello-backup.txt hello-old.txt      # rename
mv hello-old.txt reports/              # move into a directory
mv reports summaries                   # rename a directory (no -r needed)
ls; ls summaries
Output
hello.txt  images  notes.txt  projects  projects-copy  summaries
hello-old.txt  hello.txt  notes.txt

mv accepts -i (ask), -n (no overwrite) and -v (verbose) like cp. Moving within the same filesystem is instant, even for huge files, because only the name changes.

Deleting: rm and rmdir#

Terminal
rm notes.txt                     # delete a file
rm -i hello.txt                  # asks "remove regular file 'hello.txt'?" (answer n to keep it)
rmdir images                     # remove an EMPTY directory
rm -r projects-copy              # remove a directory and everything in it
ls

There's no undo. Deleted files don't go to a trash can. Safety habits:

  • Use rm -i (or -I, which asks once for big deletions) when unsure.
  • Run ls with the same pattern first: ls *.log before rm *.log.
  • Be very careful with rm -rf. -f silences all warnings. Never run rm -rf on a path built from a variable without quoting it and checking that it's set: rm -rf "${BUILD_DIR:?}/".
  • On desktops, gio trash file (or the trash-cli package) sends files to the trash instead.

Wildcards (globbing)#

The shell expands wildcards into matching file names before the command runs:

PatternMatches
*any characters (but not a leading .)
?exactly one character
[abc] / [0-9]one character from the set or range
[!abc]one character not in the set
**any depth of directories (in bash, after shopt -s globstar)
Terminal
touch report1.txt report2.txt report10.txt photo.jpg photo.png data.csv
ls report?.txt
ls *.txt
ls photo.*
ls report[12].txt
echo *.md               # no match: bash leaves the pattern as-is
Output
report1.txt  report2.txt
hello.txt  report1.txt  report10.txt  report2.txt
photo.jpg  photo.png
report1.txt  report2.txt
*.md

Because the shell does the expansion, rm *.txt really runs rm hello.txt report1.txt …. You can preview any glob with echo.

Brace expansion#

Braces generate words. Unlike globs, they don't look at existing files:

Terminal
mkdir -p site/{css,js,img}
touch site/{index,about,contact}.html
echo file{1..5}.txt
cp config.yml{,.bak} 2>/dev/null || echo "(config.yml{,.bak} expands to: config.yml config.yml.bak)"
ls site
Output
file1.txt file2.txt file3.txt file4.txt file5.txt
(config.yml{,.bak} expands to: config.yml config.yml.bak)
about.html  contact.html  css  img  index.html  js

cp file{,.bak} is a classic shortcut for "make a backup copy next to the original".

Names with spaces and special characters#

Terminal
touch "my notes.txt"
ls -l "my notes.txt"
mv my\ notes.txt my-notes.txt      # a backslash escapes a single character
ls my*
Output
-rw-r--r-- 1 ada ada 0 Oct  1 10:51 my notes.txt
my-notes.txt

A file whose name starts with - looks like an option. Use ./-file or -- to end option parsing: rm -- -file.

Checking what a file is#

Terminal
file hello.txt site photo.jpg 2>/dev/null
stat -c '%n: %s bytes, modified %y' data.csv

file inspects the content, not the extension. photo.jpg here is an empty file, whatever its name says.

Putting it together#

A safe, typical workflow for tidying a downloads folder:

Terminal
mkdir -p ~/sorted/{images,docs}
ls *.jpg *.png 2>/dev/null           # 1. preview what matches
mv -v -n *.jpg *.png ~/sorted/images/ # 2. move, never overwriting
mv -v -n *.csv ~/sorted/docs/
Output
photo.jpg  photo.png
renamed 'photo.jpg' -> '/home/ada/sorted/images/photo.jpg'
renamed 'photo.png' -> '/home/ada/sorted/images/photo.png'
renamed 'data.csv' -> '/home/ada/sorted/docs/data.csv'

Common mistakes#

  • rm -rf with a typo or an empty variable (rm -rf "$DIR"/ with DIR unset). Double-check, and use ls with the same arguments first.
  • Overwriting files with cp or mv, which replace targets silently. Use -i (ask) or -n (never overwrite) when it matters.
  • Forgetting -r when copying directories: cp folder backup fails with "omitting directory".
  • Unquoted names with spaces: rm my file.txt tries to delete two files. Quote it: rm "my file.txt".
  • Expecting a trash can. rm deletes permanently.

What's next#

Next you'll read what's inside files with cat, less, head and tail, including following log files live.

Check your understanding

Quick quiz

0/3 answered
  1. 1.What does mv report.txt archive/ do if archive is an existing directory?

  2. 2.Which command copies a directory and everything inside it?

  3. 3.Why is rm -rf $DIR/ dangerous in a script?

Finished reading?

Mark this lesson complete to track your progress.