Skip to content

Beginner · Linux and the shell · topic 5 of 57 · 35 min

Reading text: grep, less, pipes and redirection

Explanation

cat, less, head and tail read files; grep keeps only the lines that match a pattern. > sends output into a file (replacing it), >> appends, and 2> captures errors. A pipe | sends one command's output into the next, so small tools join into powerful one-liners.

Why text matters so much

On Linux almost everything is text: config files, logs, command output. If you can read, filter and save text quickly, you can troubleshoot almost anything. A few small tools do this, and they can be joined together.

Reading files

bash
$ cat /etc/hostname           # print a short file
web01.example.com
$ less /var/log/messages      # scroll a long file: Space = next page, /word = search, q = quit
$ head -n 5 /etc/passwd       # first 5 lines
$ tail -n 20 /var/log/secure  # last 20 lines
$ tail -f /var/log/messages   # follow: keep printing new lines (Ctrl+C to stop)
$ wc -l /etc/passwd           # count lines
38 /etc/passwd

grep: find matching lines

bash
$ grep asha /etc/passwd
asha:x:1000:1000:Asha Rao:/home/asha:/bin/bash
$ grep -i error /var/log/messages | tail -n 3    # -i = ignore case
$ grep -v '^#' /etc/ssh/sshd_config | grep -v '^$'  # hide comments and empty lines
$ grep -r "Listen" /etc/httpd/                   # -r = search all files under a directory
$ grep -c Failed /var/log/secure                 # -c = count matching lines
14
$ grep -n PermitRootLogin /etc/ssh/sshd_config   # -n = show line numbers
40:#PermitRootLogin prohibit-password

grep takes a regular expression, a small pattern language. The most useful parts: ^ means start of line, $ means end of line, . means any one character, and .* means "anything". So ^root matches lines that start with root, and bash$ matches lines that end with bash. Use -E for extended patterns like (error|fail).

Redirection: where output goes

Every command has three standard streams: standard input (stdin, number 0, usually the keyboard), standard output (stdout, 1, normal results) and standard error (stderr, 2, error messages). Redirection sends them somewhere else.

SyntaxMeaning
cmd > fileSend stdout into file; REPLACE the file
cmd >> fileSend stdout into file; ADD to the end
cmd 2> fileSend errors into file
cmd > file 2>&1Send both output and errors into the same file
cmd &> fileShorter bash form of the line above
cmd 2> /dev/nullThrow errors away
cmd < fileRead stdin from file
bash
$ find / -name "*.repo" > repos.txt 2> /dev/null
$ date >> /root/checks.log
$ cat repos.txt
/etc/yum.repos.d/redhat.repo
Careful: Order matters: cmd > file 2>&1 sends both into the file, but cmd 2>&1 > file sends only stdout into the file, because 2>&1 copied where stdout pointed at that moment (the screen). And > replaces a file without asking: > /etc/hosts by mistake empties it.

Pipes: joining commands

A pipe | connects the stdout of one command to the stdin of the next. Each tool does one small job, and the pipe chains them. tee is handy in the middle: it writes to a file AND passes the text on.

bash
$ grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -3
     41 203.0.113.50
     12 198.51.100.7
      3 192.0.2.44
$ ps aux | grep httpd | wc -l
9
$ dnf list installed | tee installed.txt | wc -l
512
The first line counts failed SSH logins per IP address, most first. sort sorts, uniq -c counts repeats, head keeps the top.

Common mistakes

  • Running sudo echo text > /etc/file: the redirection is done by YOUR shell, not by sudo, so it fails with "Permission denied". Use echo text | sudo tee -a /etc/file instead.
  • Reading and writing the same file in one line: sort data.txt > data.txt empties it before sort reads it. Write to a new file, then mv.
  • Forgetting that grep patterns are case-sensitive. Use -i when you are not sure.
Tip: Build pipes step by step. Run the first command, look at the output, add | and the next command, look again. You will always know which step broke.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Reading text: grep, less, pipes and redirection · 1/7

cat · less · head · tail · grep

On Linux almost everything is text. Learn to read and filter it fast.

Prefer a video by a teacher? Find free videos on “linux grep pipes redirection stdout stderr tutorial” on YouTube ↗

In real life: Spotting an SSH attack at an e-commerce company

During a sale, a Noida e-commerce company sees high CPU on a login server. The admin checks /var/log/secure with a grep pipeline and finds thousands of failed root logins from a few addresses. She saves the evidence with tee, blocks the addresses in the firewall, and later turns off password logins for SSH completely.

bash
$ grep -c "Failed password for root" /var/log/secure
4127
$ grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | tee /root/attackers.txt | head -2
   3980 203.0.113.50
    140 198.51.100.7

Practice (0/3 done)

Task 1 · Question

What does date >> log.txt do?

Task 2 · Code · Python

Write grep_lines(text, word, ignore_case=False, invert=False) that behaves like a small grep. It returns the list of lines of text that contain word. With ignore_case=True, match without caring about capitals (like grep -i). With invert=True, return the lines that do NOT contain word (like grep -v). Skip nothing else: empty lines count as lines.

Task 3 · Question

As user asha (who has sudo rights) you run: sudo echo "10.0.0.5 db01" >> /etc/hosts. It says Permission denied. Why?

Quick quiz

Question 1

1.Which sends both output and errors of cmd into out.txt?

Question 2

2.What does grep -v "^#" file show?

Question 3

3.What is /dev/null used for?

Question 4

4.In "sort names.txt | uniq -c", what does the pipe do?

Question 5

5.Which command keeps showing new lines added to a log?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which sends both output and errors of cmd into out.txt?

Answer: cmd > out.txt 2>&1

First point stdout at the file, then copy stderr to where stdout points.

What does grep -v "^#" file show?

Answer: Lines that do not start with #

-v inverts the match; ^# means a # at the start of the line.

What is /dev/null used for?

Answer: Throwing away output you do not want

Anything written to /dev/null is discarded.

In "sort names.txt | uniq -c", what does the pipe do?

Answer: Sends sort's output to uniq -c as input

A pipe connects stdout of the left command to stdin of the right one.

Which command keeps showing new lines added to a log?

Answer: tail -f

tail -f follows the file.

Which redirection sends both normal output and errors into job.log?Related

Answer: ./job.sh > job.log 2>&1

> job.log sends output to the file, then 2>&1 sends errors to the same place.

From Bash scripting, text tools and cron

Why should each step in a pipe take one argument?Related

Answer: Each step receives only the previous step's single return value

A function returns one value, which becomes the next input.

From Composition, currying and pipelines

Which module should you use to run a command that includes a pipe (|)?Related

Answer: ansible.builtin.shell

command does not use a shell, so pipes do not work.

From Ad-hoc commands and ansible-doc

Which command keeps showing new lines of a log file as they are written?Related

Answer: tail -f app.log

tail -f follows the file and prints new lines as they arrive.

From The Linux filesystem and everyday commands

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Linux and the shell” before its exam: Editing files with vim.
  2. Module 1 exam: Linux and the shell · 13 questions · 20 min, without help. 6 topics of this module still to finish first.
  3. Then the next module, Permissions, users and sudo. 57 topics left in the course before the final exam.

← Previous: Working with files: ls, cp, mv, rm, links and find