Linux / Basic: command-line foundations / Lesson 3
Read text and connect commands
Build small text-processing pipelines while keeping data, diagnostics, and file redirection under control.
On this page
Lesson goals
- Select text with grep, head, tail, and structured fields.
- Explain standard streams, pipes, and redirection order.
- Interpret pipeline status and matching failures.
Text is a sequence with boundaries
Many Linux tools process newline-delimited text. cat emits a whole file, less provides interactive paging, and head or tail selects a manageable edge. For a large log, start with a bounded view rather than flooding the terminal. A line is not necessarily a database record: quoted CSV fields and multiline messages require a parser that understands their format. Keep the source encoding and locale in mind. Human-readable alignment and translated messages can change what a naïve text filter appears to find.
Find literal text and patterns
grep selects matching lines. Use -F when the search text is literal, because punctuation otherwise may belong to a regular expression. -n adds line numbers, -i ignores case according to the applicable rules, and -v inverts selection. A regular expression such as ^WARN anchors the match at the beginning of a line. Quote the pattern so the shell does not expand its metacharacters first. Know whether a filter should match an entire field, an entire line, or any substring.
printf '%s\n' 'INFO ready' 'WARN retry' 'WARN disk' | grep -n '^WARN'
2:WARN retry
3:WARN disk
grep numbers the original input lines, so the selected warnings retain positions two and three. No real system log is read.
Three standard streams
A process normally has standard input on descriptor 0, standard output on 1, and standard error on 2. A pipe connects one command’s standard output to the next command’s standard input. It does not automatically include diagnostics. This design allows a command to produce machine-processable data while reporting trouble separately. The shell constructs the connections; the programs need not know whether input came from a keyboard, file, or pipe. Some programs change buffering when output is a pipe, which can delay visible lines.
Redirection happens before execution
The operator > opens a destination for replacement, while >> appends. The shell opens that file before the command runs. Therefore reading and redirecting to the same file can erase the input before it is read. Use a distinct new output file and inspect it before replacement. Redirections are evaluated left to right: >out 2>&1 sends both channels to out, whereas 2>&1 >out leaves standard error attached to the previous standard-output destination. Treat this ordering as descriptor copying, not as visual punctuation.
lab=$(mktemp -d)
printf '%s\n' 'pear' 'apple' 'pear' | sort | uniq -c > "$lab/counts.txt"
cat -- "$lab/counts.txt"
sort brings equal lines together, then uniq -c counts adjacent equal lines. The result contains one apple and two pears; count-padding spaces depend on the implementation.
Validate the whole chain
By default Bash reports the status of the last pipeline command. A failed producer can therefore be hidden behind a successful consumer. Bash’s pipefail option instead reports the rightmost nonzero status, or zero if all commands succeed. That still requires interpretation: grep returns 1 for no selected lines and 2 for an error. A deliberately short-reading consumer may also cause an upstream broken pipe. Inspect the pipeline’s intent and individual stages before turning every nonzero result into a generic failure message.
Common errors and fixes
A literal dot matches any character
- Why it happens
- grep interpreted the search as a regular expression.
- How to fix it
- Use grep -F for an exact literal substring.
- Prevent it next time
- Choose pattern mode explicitly.
Input file becomes empty
- Why it happens
- Output redirection truncated the same file before reading.
- How to fix it
- Restore the original from a known copy and use a distinct destination.
- Prevent it next time
- Compare input and output paths before running a transformation.
A pipeline conceals an upstream error
- Why it happens
- Only the final command’s status was checked.
- How to fix it
- Inspect stages and use Bash pipefail where appropriate.
- Prevent it next time
- Design status handling alongside the data pipeline.
Check your understanding
1. Count unique names from the lines Mina, Omar, Mina without reading a real file.
Show worked solution
Feed printf output to sort and uniq -c. Sorting is necessary because uniq groups adjacent equal lines. The result contains Mina twice and Omar once; a later wc -l would count two distinct names rather than three original records.
2. Explain why grep returning 1 need not mean a broken command.
Show worked solution
It means no input lines were selected. For an optional warning search this may be an expected clean result. A script should distinguish that outcome from status 2, which signals an actual grep error such as an unreadable input.
Key takeaways
- Keep data and diagnostics separate until combination is intentional.
- Check redirection targets and interpret every stage’s status.