Articles
sed Interview Questions: Address Ranges, Pattern Space, and Safe Text Changes
Practice sed address ranges, pattern and hold space, n/N and d/D with checked output traces, precise substitutions, and a reviewed file-change workflow.
A sed command can produce the right replacement and still be a poor answer to an interview question. You also need to explain which records it selects, what text remains in pattern and hold space between commands, and how the result reaches a file. Those are separate decisions.
This guide treats sed as a small record-processing machine. Its central argument is that reliable answers start with an execution trace, then move to a reviewed file-change plan. Memorizing substitutions without that trace makes duplicated output, unexpectedly long ranges, and a configuration file emptied by redirection harder to diagnose.
Evidence boundary: Official references below describe documented behavior. The original exercises were checked with macOS /usr/bin/sed; fourteen stdin fixtures passed. Those checks establish the displayed fixture outputs on that implementation; they do not validate every GNU/BSD version. Preparation advice is our inference from the demonstrated failure cases.
Start with Implement a robust shell CLI and explain what the command reads, prints, and changes before discussing flags.
Why does sed print every line twice?
Consider input containing A and B, one per line:
printf 'A\nB\n' | sed 'p'
The observed output is A, A, B, B. There is an explicit print and the normal end-of-cycle output. With sed -n 'p', the fixture prints each line once. Official fact: the FreeBSD sed manual documents -n as suppressing automatic output.
Describe the two output paths. Saying “p duplicates a line” is incomplete: the same command under -n does not duplicate it. Adding more print commands can change the answer again.
When debugging, trace one input record. It enters the pattern space, eligible commands execute in order, and automatic output occurs unless suppressed or bypassed by control flow. A command can print before the cycle ends, so printed text does not necessarily describe the final pattern space.
An original follow-up asks for only lines containing ERROR. Use sed -n '/ERROR/p'. Explain that the address selects the explicit print; -n prevents unmatched records from appearing through automatic output. This also explains why dropping -n is a behavior change, not a harmless shortening.
How do address ranges begin and end?
Addressing answers which pattern spaces receive a command. In this original fixture, the goal is to inspect complete marker blocks:
outside
BEGIN
x
END
between
BEGIN
y
END
after
sed -n '/BEGIN/,/END/p' markers.txt
The checked output contains both BEGIN–END blocks, including their markers. It excludes outside, between, and after. A range can finish and begin again later; it is not necessarily one permanently selected suffix of the file.
Now replace the first block with this counterexample:
BEGIN END
middle
END
after
Our fixture prints the first three lines. Both words on the first line do not make this regex range end immediately. Official fact: the NetBSD address documentation says the second regex address is not tested against the pattern space that starts the range. This is a useful difference from an informal “between two substrings” description.
Do not extend that statement to every kind of second address. A numeric endpoint needs its own analysis. Before predicting output, name whether each address is a line number, the last-input marker, or a regex.
A good follow-up asks what happens when END is missing. Predict continued selection through the remaining input, then discuss whether that result is acceptable for the task. For deleting deployment-file sections, an unmatched marker should trigger review; correct sed execution does not prove a correct configuration edit.
What are pattern space and hold space for?
Pattern space is the current working text. Hold space provides storage across processing steps. The distinction becomes useful when an exercise asks you to combine records rather than merely substitute within one line.
Our two-line fixture is header followed by alpha:
printf 'header\nalpha\n' | sed -n 'h;n;G;p'
The checked output is:
alpha
header
Here is the original state trace; ↵ represents an embedded newline:
| Step | Pattern space | Hold space | Reason |
|---|---|---|---|
| Read first record | header | Empty | Start with the first input line |
h | header | header | Copy current text into storage |
n | alpha | header | Replace working text with the next record |
G | alpha↵header | header | Append a newline and stored text |
p | alpha↵header | header | Print the combined working text |
The documented command set distinguishes replacement commands h and g from append commands H and G; x exchanges the spaces. In the trace, capital G is necessary because replacing pattern space with hold space would discard alpha.
For practice, draw both spaces after every command. That gives the interviewer a way to inspect your reasoning. If output is wrong, locate the first wrong state rather than adding commands until one sample looks right.
The trace is intentionally small. It is not a recommendation to accumulate an entire large file in hold space. Streaming input and bounded memory are different properties when a script keeps appending stored text.
What changes between n, N, d, and D?
These commands change the execution path, so capitalization deserves attention. The fixtures below use four records: A, B, C, and D.
| Checked script | Output lines | What the example exposes |
|---|---|---|
sed -n 'n;p' | B, D | The next record replaces the working text before printing |
sed -n 'N;s/\n/:/;p' | A:B, C:D | Two records share one pattern space before substitution |
sed -n 'N;P;d' | A, C | Print the first part, then discard the whole pair |
sed -n 'N;P;D' | A, B, C | Retain the suffix and restart processing it |
The second row joins each pair with a colon. Here is the runnable command:
printf 'A\nB\nC\nD\n' | sed -n 'N;s/\n/:/;p'
For the D case, after printing A, the first segment is removed and B remains. Restarting the script lets N append C, so B is printed next. The same process then prints C. On this checked implementation, the final attempt to append past EOF ends execution; the retained D is not printed by that script.
This explanation matters more than memorizing the three-letter output. Change the number of input records, the location of P, or the EOF handling and you have a different problem. Say which implementation you checked before promising portability at that boundary.
Use this as an original diagnostic question: “Why does changing lowercase d to uppercase D turn pairwise processing into an overlapping window?” Your answer should show the retained suffix and the restart, not merely call D a multiline delete.
How do you stop substitutions from changing the wrong text?
Suppose a text configuration contains:
timeout=20
#timeout=20
connect_timeout=20
timeout=20ms
The requirement is to change only a complete, uncommented timeout line whose value is an integer. This original checked substitution changes the first line to timeout=30 and preserves the other three:
sed 's/^timeout=[0-9][0-9]*$/timeout=30/' config.txt
The anchors express the whole-line boundary; the repeated digit class excludes the suffix ms. The task still needs an explicit rule for leading spaces, repeated keys, signs, and comments after the value. Broadening the regex before agreeing on those rules can quietly change unrelated settings.
Two smaller fixtures isolate other mistakes. s/x/y/ changes x x x to y x x; adding g produces y y y. And s/x/[&]/g produces [x] [x] from x x: the replacement ampersand expands to the matched text. That is why user-supplied replacement strings need replacement-side escaping as well as pattern-side handling.
Avoid claiming that shell quotes solve all escaping. Quotes control shell interpretation, while sed still interprets its regex and replacement syntax. A literal search requirement and a regex search requirement need different preparation.
If the prompt is really about modifying arbitrary JSON, XML, or escaped CSV, explain why a format-aware parser is a better fit. A substitution that passes one flat sample does not establish correct handling of nested structure or quoted delimiters.
How would you make a file change reviewable?
A safe answer first separates transformation from replacement. For the integer-timeout case, produce a candidate file using a different pathname:
sed 's/^timeout=[0-9][0-9]*$/timeout=30/' config.txt > config.candidate.txt
diff -u config.txt config.candidate.txt
Treat the candidate name as an illustrative scratch destination that must be available, not a universal production naming scheme. Review the diff, verify the expected number of changed settings, and run the configuration's real validator if one exists. A zero exit code from sed alone is not evidence that a required key matched; the old timeout may remain unchanged.
Remember that diff normally returns a nonzero status when files differ. A wrapper should distinguish an expected difference from a comparison error. Otherwise it can reject every successful edit or ignore a failed comparison.
Do not demonstrate sed ... config.txt > config.txt. The shell opens the redirected output before sed can read the original content, potentially truncating the input. The FreeBSD shell redirection reference documents this output-opening behavior. The fixture checks here never execute that destructive construction.
Implementation boundary: FreeBSD's in-place options include a backup-extension argument. Check the installed implementation's manual before translating an -i command from another platform. No single spelling in this guide is presented as a universal in-place recipe.
For a real replacement, also discuss permissions, symlinks, ownership, backup policy, and concurrent writers. An application may need a lock or maintenance boundary so it cannot overwrite a newer configuration. A rename can help a carefully designed replacement procedure, but it does not by itself solve validation, durability, or competing updates. Those are deployment decisions beyond the demonstrated stdin transformation.