Q1What does n=$(grep -c error log.txt) put into the variable n?
Using grep and awk in Scripts — Branching on the Result
This article is part of the Linux Course, where you master practical Linux skills from scratch, from basic commands through to shell scripting.
Inside a script, turn a count into a variable with n=$(grep -c ERROR access.log), sum with total=$(awk '{s+=$1} END{print s}'), and branch on if [ "$n" -ge 2 ] — a scanner built and illustrated in a browser terminal.
Calling commands inside a script — pipes and command substitution
The real power of a shell script is that you can combine general commands like `grep`, `awk`, `sed`, `sort`, and `wc` inside it.
Inside a script, you chain commands with a pipe | just as you do at the prompt, and pull their output in with command substitution, $(cmd).
Write n=$(grep -c error log.txt) and the number of matching lines from grep -c goes into the variable n.
You can also put an aggregation result into a variable, as in total=$(awk '{s+=$1} END{print s}' f).
Once a command's result is in a variable, you can use that value to change how the script behaves.
printf 'INFO ok\nERROR disk\nINFO ok\nERROR cpu\n' > sys.log # create the sample file
vi count.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# n=$(grep -c ERROR sys.log)
# echo "ERROR count: $n"
chmod +x count.sh
./count.sh # ERROR count: 2
grep -c goes into the variable n, and if branches to a warning when it is 2 or more and prints OK otherwise.| Syntax | Meaning | Example |
|---|---|---|
n=$(grep -c pat f) | Put the number of matching lines into the variable n | n=$(grep -c error log.txt) |
$(cmd | cmd) | Pull a pipeline's result into a variable | top=$(sort log.txt | head -1) |
if [ "$n" -ge 2 ]; then … | Branch on whether the count is 2 or more | if [ "$n" -ge 2 ]; then echo warn; fi |
Total it up, then act on the result — awk and branching
Beyond counts, you can also sum the numbers and decide based on the total.
total=$(awk '{s+=$1} END{print s}' f) adds up column 1 of every line and puts the sum into the variable total.
When you want the number of occurrences per word, sort first with sort f | uniq -c and count, then pull that result in with $(...).
Compare the sum against a threshold, as in if [ "$total" -gt 100 ]; then …, and you can make decisions such as "warn once the total goes over a limit".
Bundle the totalling and the branching into one script and you get a practical tool that reads data and decides what state things are in.
printf '40\n30\n50\n' > sales.txt # single-column numeric data
vi sum.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# total=$(awk '{s+=$1} END{print s}' sales.txt)
# if [ "$total" -gt 100 ]; then
# echo "total $total: goal met"
# else
# echo "total $total: not met"
# fi
chmod +x sum.sh
./sum.sh # total 120: goal met
printf 'a\na\nb\n' > tags.txt # sample file with repeated words
sort tags.txt | uniq -c # sort first, then count
# output:
# 2 a
# 1 b
if compares the total summed by awk against the threshold 20, branching to needs action when it is over and within limit when it is not.| Syntax | Meaning | Example |
|---|---|---|
awk '{s+=$1} END{print s}' f | Sum column 1 | awk '{s+=$1} END{print s}' nums.txt |
sort f | uniq -c | Sort before counting occurrences | sort tags.txt | uniq -c |
if [ "$total" -gt N ]; then … | Branch by comparing the total against threshold N | if [ "$total" -gt 100 ]; then … |
Routing output and errors — > and 2>
Sometimes you want a script's result kept in a file instead of on screen.
./scan.sh > report.txt writes the normal output (standard output) into report.txt.
Send error messages to standard error with echo "..." 1>&2, and ./scan.sh > report.txt 2> error.log lets you keep the good results and the errors in separate files.
vi job.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# echo "processing started" # standard output
# echo "note: input was empty" 1>&2 # standard error
chmod +x job.sh
./job.sh > out.txt 2> err.txt # send output and errors to separate files
cat out.txt # processing started
cat err.txt # note: input was empty
> report.txt and standard error to 2> error.log, so the two land in separate files.| Syntax | Meaning | Example |
|---|---|---|
cmd > out | Write standard output to a file | ./scan.sh > report.txt |
echo "…" 1>&2 | Send a message to standard error | echo "failed" 1>&2 |
cmd > out 2> err | Route output and errors to separate files | ./scan.sh > report.txt 2> error.log |
Knowledge Check
Answer each question one by one.
Q2What does if [ "$n" -ge 2 ]; then … do?
Q3In ./scan.sh > report.txt 2> error.log, what does 2> route?