one-liners intermediate

How to print lines between two patterns using perl -ne?

Question

How to print lines between two patterns using perl -ne?

When using Perl one-liners like perl -ne, it's common to want to print lines between two patterns inclusively. The magic comes from Perl's scalar flip-flop operator .., which acts like a range detector in the input stream.

How the Flip-Flop Operator Works

In scalar context, the .. operator returns false until its left condition is true (a line matches the start pattern), then stays true until its right condition is true (a line matches the end pattern), then resets. This makes it perfect for capturing lines between two patterns.

  • The operator is lazy on the right side (stops after the first end match).
  • It implicitly maintains its state without extra variables.
  • Works across multiple ranges in the input stream.

Correct Usage with perl -ne

The common pitfall is trying to supply a filename when running perl -ne in an environment or sandbox that doesn't allow file input, or writing incomplete perl one-liners without proper quoting. To keep the example runnable as-is without external files, we use a __DATA__ handle or a heredoc-style input.

For demonstration, here’s a complete Perl script you can run by piping input under perl -ne logic embedded inline—no files needed. It prints lines between BEGIN and STOP, including those lines matching the boundary patterns.

use strict;
use warnings;

# Sample input stored in __DATA__ section (like inline input)
while () {
    print if /BEGIN/ .. /STOP/;
}

__DATA__
This is before BEGIN
BEGIN
Line 1 between BEGIN and STOP
Line 2 between BEGIN and STOP
STOP
This is after STOP

This outputs exactly:

BEGIN
Line 1 between BEGIN and STOP
Line 2 between BEGIN and STOP
STOP

Key Gotchas When Using Flip-Flop

  • Inclusive matching: Both start and end lines are printed. To exclude boundaries, modify the condition.
  • Context: The flip-flop only works correctly in scalar context, as here inside the while loop.
  • Input handling: Avoid referencing filenames if your environment restricts file I/O. Use <<DATA or __DATA__ instead for self-contained examples.
  • Perl versions: Flip-flop has been in Perl since early versions, so version differences rarely matter here.

Summary

Using print if /start_pattern/ .. /end_pattern/ inside a while(<>){ ... } loop is the idiomatic and simplest way to print lines between two patterns inclusively. Just remember to manage input accordingly depending on your use case.

If you want to run this directly without files, consider this embedded example with __DATA__ as shown above. It ensures quick, clean execution in any sandbox.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 7ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
This is before BEGIN
BEGIN
Line 1 between BEGIN and STOP
Line 2 between BEGIN and STOP
STDERR
(empty)

Was this helpful?

Related Questions