MA-CLI1 · Module 1.6
Inspecting files and directory trees
Topics: cat · less · ls -R
Overview
Module 1.6 — Inspecting files and directory trees
Before you copy, chmod, or delete, you inspect: cat, less, head/tail, and ls -lR. These commands are mostly read-only.
By the end you should be able to: choose the right viewer; walk a tree with details; run a short verification pass (pwd → ls -lR → cat/less).
Scroll Core ideas → worked examples → Quiz. Plan on roughly 45–55 minutes.
Concepts
Core ideas — seeing what is on disk
Over the last few modules Sam has made folders, copied files, moved them, and set permissions on them. All of that was changing things. This module is about the quieter half of terminal work: looking. Before you copy, rename, lock down, or delete anything, you want to see what is really there. After you have changed something, you want to see that the change did what you meant.
The good news is that every command in this module is read-only. None of them alters a file, so you can run them freely, experiment, and be wrong without consequences. Think of them as a set of windows into the tidewatch project: some windows show the contents of a file, and others show facts about files and folders, such as who owns them and how big they are.
Print a file — cat
cat notes/field_log.txt
cat takes the whole file and prints it to the terminal, from the first line to the last, and then returns you to the prompt. The name is short for "concatenate," which hints at its second ability: give it several files and it prints them back-to-back, in the order you typed them.
cat notes/field_log.txt notes/private_draft.txt
Here the entire log appears first, and the draft follows immediately. There is no divider between them, so if the first file does not end with a newline, the last line of one can run into the first line of the next. If you need to know where one file stopped, print them in separate commands.
cat is the right tool when a file is short: a few lines of notes, a small configuration, a one-line script. It is the wrong tool for something long. A file with ten thousand lines will scroll past in a blur, and you will be left looking at only the very end. That is the cue to reach for a pager.
Page through a file — less (and more)
less data/raw/gauge_a.csv
less opens the file in a viewer that shows one screenful at a time and waits for you. Nothing is printed to your scrollback; the viewer takes over the window until you leave it. The handful of keys worth learning:
| Key | What it does |
|-----|--------------|
| Space | forward one page |
| b | back one page |
| Down / Up arrows | one line at a time |
| /word | search forward for word (then n for the next match) |
| g / G | jump to the start / the end |
| q | quit and return to the prompt |
If you remember only one key, remember q. Many beginners feel stuck inside less simply because they do not know how to get out. Press q and you are back at the prompt.
There is an older sibling called more. It also shows one page at a time and also uses Space and q, but it is more limited (in many versions it cannot scroll backwards). The joke in the name less is that "less is more." On most systems less is the better default, and when a task says "display this in pages," less is your answer.
The two ends of a file — head and tail
Sometimes you do not want the whole file, only a glimpse of its beginning or its end.
head -n 3 data/raw/gauge_a.csv # the first 3 lines
tail -n 5 notes/field_log.txt # the last 5 lines
Without -n, both commands show 10 lines. The -n option says how many lines you want. These two are made for common situations:
- A data file usually has its column names on the first line.
head -n 3shows the header and a couple of sample rows, which is often enough to tell whether the file is the one you expected. - A log grows at the bottom, so the newest news is at the end.
tail -n 5shows what happened most recently.
There is one more form you will meet:
tail -f notes/field_log.txt
-f means "follow." tail prints the last lines and then keeps waiting, printing new lines as they are added. It does not finish by itself. Press Ctrl-C to stop it.
Detailed listing — ls -l and ls -lh
Plain ls gives names and nothing else. Add -l (long) and every entry becomes a full line of facts:
ls -l notes/
total 16
-rw-r--r-- 1 sam crew 186 Oct 14 09:30 field_log.txt
-rw------- 1 sam crew 74 Oct 14 09:35 private_draft.txt
From left to right: the type and permission column (the one you decoded in Module 1.5), the link count, the owner, the group, the size in bytes, the time last modified, and the name. The total line at the top is a disk-usage figure for the listing; it is rarely what you are looking for, so skip over it.
Byte counts are easy to compute for tiny files but hard to feel for big ones. Add -h (human-readable) and sizes turn into K, M, and G:
ls -lh data/raw/
-lh is the same table, with 2.4M where -l would have shown 2516582. The two flags can be written together as -lh; the order inside does not matter.
Remember that ls does not show names beginning with a dot unless you add -a. If a file seems to be missing and its name starts with ., try ls -la.
The whole tree — ls -lR
So far you have inspected one folder at a time. But a project like tidewatch/ is a tree, and you will often want to see the entire tree and its details in a single command. Two flags combine for that:
| Flag | Meaning |
|------|---------|
| -R | Recursive: enter every subdirectory and list it too |
| -l | Long: show permissions, owner, size, date, and name for every entry |
ls -lR tidewatch/
Read this as: "list tidewatch/, and everything beneath it, with full details." The output is organised as blocks. Each block begins with a header naming a directory and ending in a colon, followed by that directory's entries:
tidewatch/:
total 0
drwxr-xr-x 2 sam crew 64 Oct 14 09:00 archive
drwxr-xr-x 4 sam crew 128 Oct 14 09:00 data
drwxr-xr-x 2 sam crew 64 Oct 14 09:00 drafts
drwxr-xr-x 4 sam crew 128 Oct 14 09:35 notes
drwxr-xr-x 3 sam crew 96 Oct 14 09:30 scripts
tidewatch/notes:
total 16
-rw-r--r-- 1 sam crew 186 Oct 14 09:30 field_log.txt
-rw------- 1 sam crew 74 Oct 14 09:35 private_draft.txt
(Real output continues with a block for every other folder, and your dates and sizes will differ.)
Here is how to read it. A line that starts with d is a directory, and the next block will describe what is inside it. A line that starts with - is a regular file. The header tells you which folder you are looking at, so you never confuse notes/field_log.txt with a similarly named file elsewhere.
It helps to compare the four variants side by side, because each gives you less than -lR:
| Command | Levels shown | Details per line |
|---------|--------------|------------------|
| ls tidewatch/ | one | names only |
| ls -R tidewatch/ | whole tree | names only |
| ls -l tidewatch/ | one | full details |
| ls -lR tidewatch/ | whole tree | full details |
Use -lR when you want an honest overall picture: after you create folders, after you move files, or before you change permissions in bulk. One caution: on a big folder, the output can run to thousands of lines. Start from a small directory such as tidewatch/, never from your home folder.
The verification ritual
Putting these tools together gives you a short routine you can use after any piece of work. Call it a verification pass.
pwd— confirm where you are. A command run from the wrong folder is the most common reason output looks "wrong."ls -lRon the project folder — confirm the structure (are the folders and files where you expect?) and the permissions (are the private ones really private?).catorlesson one or two key files — confirm the content (is the draft the draft, and is the script the script?).
The order matters for a reason. Position first, because everything else depends on it. Structure second, because a missing file makes the third step meaningless. Content last, because it is the most detailed and takes the longest.
When something does not match, do not guess. Name the mismatch precisely: "the file I expected in data/processed is showing up in data/raw." A precise sentence usually points straight at the fix.
Common confusions
- "
catandlessshow different things." They show the same text; the difference is delivery.catpours it all out, andlesshands it to you a page at a time. - "
ls -lshows what is inside the files." It shows facts about the files (size, owner, date). To see inside, usecat,less,head, ortail. - "I pressed keys in
lessand nothing happens." Read the bottom of the window: if you are inside the viewer, pressqto leave. - "
headandtailchange the file." They only display. The file on disk is untouched.
Self-study checklist
- Say when you would choose
lessovercat, and which key leavesless. - Run
head -n 3andtail -n 3on a file of your own, and say what each shows. - Run
ls -lon a file and point to the owner, the group, and each permission triple. - Explain what
ls -lR tidewatch/shows that plainls tidewatch/does not. - Recite the verification pass in order, and say why the order is sensible.
Examples
Worked examples — inspecting the tidewatch tree
Sam has spent the afternoon reorganising tidewatch/. Now it is time to look at the result carefully. Each scene gives a situation, the commands, an interpretation, and a takeaway. Your output will differ in dates and sizes; focus on the shape.
First, a small setup so you can follow along:
cd ~/cli-practice
mkdir -p tidewatch/notes tidewatch/drafts tidewatch/scripts tidewatch/archive
mkdir -p tidewatch/data/raw tidewatch/data/processed
printf 'gauge,time,level_cm\nA,06:00,112\nA,07:00,118\nA,08:00,131\nA,09:00,149\nA,10:00,160\n' > tidewatch/data/raw/gauge_a.csv
printf 'Oct 12: calm morning\nOct 13: surge at gauge A\nOct 14: repaired cable\n' > tidewatch/notes/field_log.txt
echo 'Draft thoughts about the surge' > tidewatch/notes/private_draft.txt
printf '#!/bin/sh\necho syncing\n' > tidewatch/scripts/sync_readings.sh
chmod 600 tidewatch/notes/private_draft.txt
chmod 755 tidewatch/scripts/sync_readings.sh
Scene 1 — A map of everything
Scene. Sam wants one picture of the whole project, with details, before touching anything else.
pwd
ls -lR tidewatch/
/Users/sam/cli-practice
tidewatch/:
total 0
drwxr-xr-x 2 sam crew 64 Oct 14 09:00 archive
drwxr-xr-x 4 sam crew 128 Oct 14 09:00 data
drwxr-xr-x 2 sam crew 64 Oct 14 09:00 drafts
drwxr-xr-x 4 sam crew 128 Oct 14 09:00 notes
drwxr-xr-x 3 sam crew 96 Oct 14 09:00 scripts
tidewatch/data:
total 0
drwxr-xr-x 3 sam crew 96 Oct 14 09:00 processed
drwxr-xr-x 3 sam crew 96 Oct 14 09:00 raw
tidewatch/data/raw:
total 8
-rw-r--r-- 1 sam crew 65 Oct 14 09:01 gauge_a.csv
tidewatch/notes:
total 16
-rw-r--r-- 1 sam crew 65 Oct 14 09:01 field_log.txt
-rw------- 1 sam crew 31 Oct 14 09:01 private_draft.txt
tidewatch/scripts:
total 8
-rwxr-xr-x 1 sam crew 26 Oct 14 09:01 sync_readings.sh
(Empty folders such as archive, drafts, and data/processed also get a header block; they are left out here to save room.)
Interpretation. Start with the first command: pwd says Sam is in ~/cli-practice, one level above tidewatch, which is why the path in the second command begins with tidewatch/. In the listing, each d line is a folder that gets its own block further down. The details also tell a second story: private_draft.txt shows -rw-------, so it is private; sync_readings.sh shows three x characters, so anyone can run it; and the other files are plain readable data.
Takeaway. ls -lR gives you structure and permissions together. Read headers for where, then each line for what.
Scene 2 — Choosing between cat and less
Scene. Sam wants to check notes/field_log.txt. The file has three lines.
cat tidewatch/notes/field_log.txt
Oct 12: calm morning
Oct 13: surge at gauge A
Oct 14: repaired cable
Three lines fit comfortably in the window, so cat is ideal. Now imagine the log had grown to six hundred lines. Sam would open it as a book instead:
less tidewatch/notes/field_log.txt
Inside less, Sam presses Space to move forward a page, b to go back, types /surge to jump to the first line containing the word, presses n to hop to the next match, and finally q to return to the prompt.
Interpretation. Both commands show the same text. The deciding factor is length: if the content fits on one screen, cat is quicker; if not, less lets you read at your own pace and search.
Takeaway. When unsure, use less. It is never wrong, and q always gets you out.
Scene 3 — A quick look at the ends
Scene. Sam has a readings file and wants to confirm two things: that the column names are correct, and what the most recent reading was.
head -n 2 tidewatch/data/raw/gauge_a.csv
tail -n 2 tidewatch/data/raw/gauge_a.csv
gauge,time,level_cm
A,06:00,112
A,09:00,149
A,10:00,160
Interpretation. The first two lines are the header and the first reading; the last two are the most recent. The level rose from 112 cm at 06:00 to 160 cm at 10:00, which matches the surge noted in the log. Sam learned that from four lines of output without opening the whole file.
Takeaway. head is for "what is this file?" and tail is for "what happened last?"
Scene 4 — Find the mismatch
Scene. A teammate says the cleaned readings are ready in data/processed/. Sam does the verification pass and finds that something does not add up. Suppose the teammate's script ran in the wrong place and left the output beside the raw data.
Step 1: where am I?
pwd
/Users/sam/cli-practice
Step 2: look at the data folders.
ls -lR tidewatch/data
tidewatch/data:
total 0
drwxr-xr-x 2 sam crew 64 Oct 14 10:15 processed
drwxr-xr-x 4 sam crew 128 Oct 14 10:15 raw
tidewatch/data/processed:
total 0
tidewatch/data/raw:
total 16
-rw-r--r-- 1 sam crew 65 Oct 14 09:01 gauge_a.csv
-rw-r--r-- 1 sam crew 52 Oct 14 10:14 gauge_a_clean.csv
Step 3: state the mismatch precisely. The teammate said the clean file is in processed/. The listing says processed/ has no entries at all (total 0, nothing below it), while gauge_a_clean.csv sits in raw/. That is a location mismatch.
Step 4: check the content before fixing. Moving the wrong file would only make things worse, so look first.
head -n 3 tidewatch/data/raw/gauge_a_clean.csv
gauge,level_cm
A,112
A,118
The file really is the cleaned version: it has fewer columns than the raw one. Only its location is wrong.
Step 5: fix and re-verify.
mv tidewatch/data/raw/gauge_a_clean.csv tidewatch/data/processed/
ls -lR tidewatch/data
tidewatch/data:
total 0
drwxr-xr-x 3 sam crew 96 Oct 14 10:20 processed
drwxr-xr-x 3 sam crew 96 Oct 14 10:20 raw
tidewatch/data/processed:
total 8
-rw-r--r-- 1 sam crew 52 Oct 14 10:14 gauge_a_clean.csv
tidewatch/data/raw:
total 8
-rw-r--r-- 1 sam crew 65 Oct 14 09:01 gauge_a.csv
Interpretation. The second listing now matches the sentence "clean data in processed/, raw data in raw/." Notice that the size (52) and time stayed the same: mv relocated the file without rewriting it.
Takeaway. The loop is: state what you expect, inspect, name the difference precisely, check content, fix, inspect again. Inspecting twice is what turns a hopeful fix into a confirmed one.
Scene 5 — Sizes you can feel
Scene. Sam is curious how large the sandbox files are and asks for friendlier numbers.
ls -lh tidewatch/data/raw
total 8
-rw-r--r-- 1 sam crew 65B Oct 14 09:01 gauge_a.csv
For tiny files -h changes little. On a larger file, say a season of readings, the same command would show 2.4M where -l shows 2516582.
Takeaway. Use -lh whenever the size matters to a human eye; use -l when you need exact bytes.
Practice check — inspecting files
Multiple-choice check from the Matheion app lesson. Pick an answer for each question, then submit.
1.Which command pages through a long file interactively?
2.To list every file and subdirectory under `tidewatch/` with permissions, size, and dates on each line, you use…
3.`cat a.txt b.txt` output order?
4.`tail -n 5 log.txt` shows…
5.Inside `less`, which key searches forward for the word `surge`?
6.Sam wants a quick look at only the first three lines of `data/raw/gauge_a.csv` to check the column names. Best choice?
7.After reorganising `tidewatch/`, which sequence is the sensible verification pass?