Lesson 03 of 19 · Level 1 — Beginner: everyday commands
Reading & searching text
Most of Linux is text: logs, configs, command output. Read it (cat, less, head, tail), search it (grep), and connect small commands into powerful one-liners with pipes and redirection.
Everything is text
Configuration files, logs, and the output of almost every command are plain text. If you can read, search and reshape text quickly, you can troubleshoot almost anything.
Imagine the computer keeps a huge diary. cat reads the whole diary out loud. less lets you flip through it page by page. grep is a highlighter pen that shows only the lines with a word you care about. And a pipe (|) is a conveyor belt: one machine's output goes straight into the next machine.
Reading files
| Command | Best for |
|---|---|
cat file |
Short files |
less file |
Long files: scroll, search with /word, n for next, G to the end, q to quit |
head -n 20 file |
The beginning |
tail -n 50 file |
The end: where the newest log lines are |
tail -f file |
Watching a log live |
$ tail -f /var/log/syslog
Sep 27 09:14:02 web-01 systemd[1]: Started nginx.service - A high performance web server.
Sep 27 09:14:05 web-01 kernel: [ 1043.21] eth0: link up
Searching with grep
$ grep -i "error" /var/log/nginx/error.log # case-insensitive
$ grep -rn "listen" /etc/nginx/ # recursive, with line numbers
/etc/nginx/sites-enabled/default:22: listen 80 default_server;
$ grep -v "^#" /etc/ssh/sshd_config | grep -v "^$" # hide comments and blank lines
$ grep -c "Failed password" /var/log/auth.log # count matches
grep -E enables extended regular expressions: grep -E "error|fail|denied" matches any of the three.
Pipes: small tools, big results
The pipe | sends the output of one command into the next. Each tool does one thing well:
| Tool | Does |
|---|---|
wc -l |
Count lines |
sort / sort -rn |
Sort alphabetically / by number, largest first |
uniq -c |
Collapse repeated adjacent lines, with counts (sort first!) |
cut -d' ' -f1 |
Take field 1, splitting on spaces |
head / tail |
Keep the first / last lines |
Which IP addresses hit a web server most?
$ cut -d' ' -f1 /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -5
1843 203.0.113.45
912 198.51.100.7
301 192.0.2.19
88 203.0.113.9
12 198.51.100.200
Redirection: output to files
Every program has three standard streams: stdin (0, input), stdout (1, normal output) and stderr (2, errors).
| Syntax | Meaning |
|---|---|
cmd > file |
stdout to file (overwrites) |
cmd >> file |
stdout, appended |
cmd 2> file |
stderr only |
cmd > file 2>&1 |
both, to the same file |
cmd < file |
read input from a file |
cmd 2>/dev/null |
throw errors away |
$ find / -name "*.conf" 2>/dev/null > conf-files.txt # hide permission errors, keep results
$ wc -l conf-files.txt
214 conf-files.txt
> overwrites without asking
sort file > file destroys file (the shell empties it before sort reads it). Write to a new file, then move it back.
Try it: investigate a log
Use /var/log/syslog (Ubuntu), or journalctl --no-pager > ~/journal.txt to make a file from the journal.
- How many lines does it have? (
wc -l) - Show the last 20 lines, then follow it live with
tail -fwhile you runlogger "hello from the lab"in another terminal. - Count lines containing "error" or "fail" (case-insensitive).
- Which programs log the most? Look at one line first and count the fields: with a classic timestamp (
Sep 27 09:14:02 host prog[pid]:) the program is field 5; with an ISO timestamp (2026-09-27T09:14:02… host prog[pid]:, used by newer Ubuntu releases) it's field 3. Then:awk '{print $5}' file | sort | uniq -c | sort -rn | head(use$3for ISO format). - Save only the lines with "fail" to
~/fails.txt, then append today's date to the end of it with>>.
Going deeper: text power tools
awkhandles columns and simple logic:awk '$9 >= 500 {print $7}' access.logprints the URLs of server errors in combined log format.sededits streams:sed -n '100,120p' fileprints lines 100–120. Both are covered in Bash Scripting.grep -F(fixed strings) is much faster on huge files when you don't need regex.zgrepsearches compressed rotated logs (*.gz) directly.- For JSON logs, use
jq:jq -r 'select(.level=="error") | .msg' app.json. teewrites to a file and the screen:cmd | tee out.txt.sudo teeis how you write to root-owned files from a pipe.
Recap
- Read with
cat,less,head,tail(-fto follow). - Search with
grep(-i,-r,-n,-v,-C,-E). - Connect tools with pipes; count and rank with
sort | uniq -c | sort -rn. - Redirect with
>,>>,2>,2>&1, and remember that>overwrites.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.