Every command so far has printed to the screen. The sends that output somewhere better: into another command.
The vertical bar
cat server.log | grep ERROR
ERROR database timeout
ERROR disk full
Read it left to right:
cat server.logproduces the file’s text|catches that text instead of letting it hit the screengrep ERRORreceives it and filters it- What survives gets printed
Notice that grep has no file name after it. It does not need one — it is reading from the pipe.
Note
Most of these tools follow the same convention: given a file name, read the file; given none, read whatever comes in through the pipe. That one rule is what makes them all connectable.
Quick check
Why does grep take no file name in `cat notes.txt | grep TODO`?
Chains
Pipes stack. Each stage takes what the last one produced:
grep INFO server.log | wc -l
grep pulls out the routine lines, wc -l counts them, and you get a single number back. Three lines of thinking, one line of typing.
You can keep going:
cat server.log | grep -v INFO | wc -l
Take the log, drop the routine lines, count what is left. Nothing here is a special “log analysis” tool — it is three general commands wired together.
Quick check
What does `cat data.txt | grep error | wc -l` produce?
Building a chain without guessing
Do not write a four-stage pipe and hope. Build it one stage at a time and look at the output after each:
cat server.log
cat server.log | grep -v INFO
cat server.log | grep -v INFO | wc -l
Each step is checkable. When the answer at the end looks wrong, you already know which stage to suspect.
Tip
This is exactly how to read a long pipeline an AI agent hands you: cover everything after the first | and ask what the first part produces. Then uncover one stage at a time. A ten-stage pipeline is never complicated at any single point.
Quick check
An agent gives you a pipeline with four stages and you are not sure about it. What is the cheapest way to understand it?
Where it goes next
Combine what you already have and the pipe becomes genuinely powerful:
find . -name "*.log" | wc -l
That counts log files anywhere in the project — a question neither command could answer alone.
Try it
cat server.log— the whole file, six lines.cat server.log | grep ERROR— the same data, filtered down to two.grep INFO server.log | wc -l— a count of the routine lines instead of the lines themselves.
Step 3 is worth a second look: the output changed shape entirely. Lines went in, a number came out. Each stage in a pipe is free to transform, not just filter.