sed Part II · Module 5 · Filtering and Line Operations
Printing and Suppressing Output
Part II so far has been about changing lines and choosing which ones. Module 5 is the rest of what sed can do to a line — print it, delete it, replace it, or add new lines around it — and it starts with printing, because printing is the one you have been using since Module 2 without it ever being explained. The key fact is that sed has two completely separate ways of producing output: the automatic print at the end of every cycle, and the explicit p command. They are independent, they can both fire on the same line, and almost every piece of sed output that looks wrong is the two of them running together.
Foundation15 min readsedPart IIFilteringUVM LogsFundamentals
Part II · Module 5 · Chapter 5.1 · Printing and Suppressing Output
1. Two Sources of Output
Chapter 2.2 described sed's cycle: read a line, run the commands, print the pattern space, repeat. That print at step four is automatic — you never asked for it, and it is why sed 's/a/b/' file gives you the whole file back rather than only the changed lines.
The p command is the other source. It prints the pattern space too, but only when you say so, and only on the lines its address selects.
auto-print happens at the end of every cycle ← switched off by -n
p happens where you put it in the script ← runs on its addressThose two facts combine into exactly three useful arrangements, and one that catches people out. All four are below, measured on the same file.
2. Three Commands, Three Different Counts
A simulation log, six lines, two of them errors:
cat -n logs/sim.log 1 UVM_INFO @ 0: reset asserted
2 UVM_INFO @ 120: reset released
3 UVM_ERROR @ 980: data mismatch exp=8'hA5 act=8'h5A
4 UVM_INFO @ 1200: scoreboard drain
5 UVM_ERROR @ 1510: timeout waiting for ready
6 UVM_INFO @ 2000: test doneArrangement one — -n plus p. This is a filter.
sed -n '/UVM_ERROR/p' logs/sim.logUVM_ERROR @ 980: data mismatch exp=8'hA5 act=8'h5A
UVM_ERROR @ 1510: timeout waiting for readyTwo lines. Auto-print is off, so the only output is what p produced, and p only ran on the two lines its address selected. This is the single most common sed invocation there is.
Arrangement two — p without -n. This is almost never what you want.
sed '/UVM_ERROR/p' logs/sim.logUVM_INFO @ 0: reset asserted
UVM_INFO @ 120: reset released
UVM_ERROR @ 980: data mismatch exp=8'hA5 act=8'h5A
UVM_ERROR @ 980: data mismatch exp=8'hA5 act=8'h5A
UVM_INFO @ 1200: scoreboard drain
UVM_ERROR @ 1510: timeout waiting for ready
UVM_ERROR @ 1510: timeout waiting for ready
UVM_INFO @ 2000: test doneEight lines from a six-line file. Every line was printed once by auto-print, and the two matching lines were printed again by p. The errors are duplicated.
This is worth recognising on sight. If you ever see sed output with some lines doubled, you have left out -n — the pattern is fine, the plumbing is not.
Arrangement three — -n plus an unaddressed p. This is cat.
sed -n 'p' logs/sim.log | wc -l 6Six lines: auto-print off, and p with no address runs on every line, so each line is printed exactly once. Useless on its own, and a useful sanity check — if you are unsure whether -n is doing what you think, this is the command that isolates it.
The counts side by side make the point better than the output does:
| Command | Output lines | What it is |
|---|---|---|
sed -n '/UVM_ERROR/p' | 2 | a filter |
sed '/UVM_ERROR/p' | 8 | the file, with matches duplicated |
sed -n 'p' | 6 | cat, the long way |
sed -n '' | 0 | auto-print off, nothing asked for |
Same six-line file every time.
3. What -n Actually Does
-n has exactly one effect: it removes the automatic print from step four of the cycle. It does not change matching, it does not change the commands, and it does not suppress anything a p asks for.
That is why the empty script behaves as it does. Without -n:
sed '' logs/sim.log | wc -l 6The whole file, produced entirely by auto-print. With -n:
sed -n '' logs/sim.logNothing at all, exit status 0. The cycle still ran six times; it just never printed.
The practical rule: once you write -n, every line you want has to be asked for. That is a feature — it turns sed into a tool that emits only what you selected, which is what makes it useful in a pipeline.
4. The p Flag Is Not the p Command
These two look alike and do different jobs:
sed -n '/UVM_ERROR/p' the p COMMAND, on an address
sed -n 's/UVM_ERROR/ERROR/p' the p FLAG, on a substitutionThe command prints lines that match an address. The flag prints lines where the substitution actually changed something.
sed -n 's/UVM_ERROR/ERROR/p' logs/sim.logERROR @ 980: data mismatch exp=8'hA5 act=8'h5A
ERROR @ 1510: timeout waiting for readyTwo lines, and they are printed after the substitution — you are reading the new text, not the old. That difference is what makes this the dry-run idiom from Chapter 3.1: it shows you exactly what the lines would become.
And when nothing matches, it says so by saying nothing:
sed -n 's/UVM_FATAL/FATAL/p' logs/sim.logEmpty output, exit status 0. Compare that with running the same substitution without -n, which would print all six lines unchanged and tell you nothing. This is the difference between a command that reports and a command that merely runs, and it is why Chapter 7.2 builds its whole dry-run procedure on the p flag.
5. Printing a Region
p takes any address, including the ranges from Chapter 4.4. Here is a timing report with two paths:
cat -n sta/timing.rpt 1 Startpoint: u_alu/rd_data_reg[3]
2 Endpoint: u_fifo/wr_ptr_reg[0]
3 data arrival time 1.842
4 data required time 2.100
5 slack (MET) 0.258
6 Startpoint: u_fifo/rd_ptr_reg[1]
7 Endpoint: u_alu/op_reg[2]
8 data arrival time 2.410
9 slack (VIOLATED) -0.110sed -n '/^Startpoint/,/slack/p' sta/timing.rpt | wc -l 9Nine lines — the whole file, because the range reopened and there are exactly two paths that between them cover every line. Chapter 4.4 measured that behaviour on a longer report; it is worth re-checking here because "extract the path block" is the single most common reason to use p with a range, and on a file of only paths it extracts everything.
6. Where This Fits
Printing is half of filtering. The other half is deleting — keeping everything except what you select — and the two are often interchangeable:
sed -n '/UVM_ERROR/p' keep only the errors, by printing them
sed '/UVM_ERROR/!d' keep only the errors, by deleting the restBoth give the same two lines here. Which you reach for is mostly about which description is shorter: "print what I want" or "delete what I do not". Chapter 5.2 is the delete side, and it has one behaviour that printing does not — d ends the cycle, so commands after it never run.
One more output route exists and is out of this module's scope: the w command writes the pattern space to a file rather than to standard output, which is how a single pass can split a log into several files. It appears in Module 8's pipeline work, where there is a reason to want it.
7. Think It Through
1. Your filter prints every error twice. What is the one-character fix?
Add -n. The duplicates are auto-print and p both firing on the matching lines — six lines from auto-print plus two from p gave the eight-line output in section 2. The pattern is not the problem.
2. sed -n '/UVM_WARNING/p' sim.log prints nothing. Name two different explanations and how to tell them apart.
Either the file genuinely has no warnings, or your pattern is wrong — a case difference, a typo, or the log spelling it differently. Distinguish them by widening: sed -n '/UVM/p' should print something if the log is a UVM log at all, and sed -n 'p' sim.log | wc -l confirms sed is reading the file you think it is. Working outward from a pattern you are sure of is faster than staring at the one that failed.
3. When is sed -n 's/old/new/p' better than sed -n '/old/p'?
Whenever you are about to make the change. The flag prints the line after substitution, so you read the result rather than the input, and it only prints lines the substitution actually altered. The address version prints lines that merely contain the pattern, which over-reports if your pattern and your substitution differ — and they differ more often than you would expect, usually by an anchor.
4. What does sed -n 'p;p' do, and why would anyone notice?
Prints every line twice — two p commands, both unaddressed, both firing, with auto-print off. Nobody writes it deliberately; it is what a half-finished edit looks like when someone adds a p without removing an earlier one. Recognising doubled output as a plumbing symptom rather than a pattern symptom is the point of section 2.
5. You want the first five lines of a report and sed -n '1,5p' works. Why might sed '5q' be better on a very large file?
Because -n '1,5p' reads the entire file — the cycle runs on every line, printing nothing for most of them — while q quits as soon as it has what you want. On a 50 MB log the difference is real. q is a Module 6 command; it is worth knowing that an address which selects early lines does not, by itself, stop sed from reading the rest.
8. Summary
- sed has two output sources: the automatic print at the end of each cycle, and the explicit
pcommand. They are independent. -nremoves auto-print and nothing else. The cycle still runs; it just stops printing for you.sed -n '/pat/p'is a filter — the most common sed invocation there is.sed '/pat/p'without-nduplicates the matches. Eight lines came out of a six-line file. Doubled output means a missing-n, not a bad pattern.sed -n 'p'iscat, and a useful way to check that-nis behaving.- The
pflag on a substitution is not thepcommand. The flag fires only when the substitution changed something, and prints the result — which is why it is the dry-run idiom. - An empty result from the
pflag is informative; the same substitution without-nwould print the whole file and tell you nothing. Pispuntil the pattern space holds more than one line — Module 6.- Printing and deleting are two ways to filter.
sed -n '/E/p'andsed '/E/!d'gave the same two lines.
You can now control exactly what comes out. The next question is what to do with the lines you do not want, and whether to describe them or describe the survivors. Chapter 5.2 — Deleting Lines covers d, including the behaviour that makes it different from every command so far: it does not just remove the line, it abandons the rest of the script for that line.
Where this fits
Part of the sed curriculum.
