如何使用sed提取首个BEGIN与最后一个END之间的文本?
Your original command sed -n -e '/^BEGIN$/,/^END$/p' logs.txt works by matching each individual pair of BEGIN and the immediately following END—that’s why it only pulls out two separate blocks instead of the full range from the first BEGIN to the last END.
Working Solution Command
To capture everything from the first occurrence of BEGIN all the way to the last occurrence of END, use this sed command:
sed -n '1,/BEGIN/{/BEGIN/!d}; /END/{p;q}; p' logs.txt
Breakdown of How It Works
Let’s break down each part to make it clear:
-n: Turns off sed’s default behavior of printing every line, so we only output what we explicitly specify.1,/BEGIN/{/BEGIN/!d}: Handles lines from the start of the file up to the firstBEGIN:- For any line in this range that doesn’t contain
BEGIN, we delete it (!d). This skips all pre-BEGIN lines and keeps only the first line withBEGIN.
- For any line in this range that doesn’t contain
/END/{p;q}: When we hit a line withEND:- Print the line (
p), then immediately quit sed (q). Since sed processes lines top-to-bottom, this ensures we stop at the finalENDin the file.
- Print the line (
p: Prints all lines that fall between the firstBEGINand the lastEND—these lines don’t trigger the previous two rules, so we explicitly print them.
Test with Your Input
Given your input (formatted as multi-line for clarity):
line1 BEGIN line2 line3 END line4 line5 BEGIN line6 line7 ENDED END line8 END line9 line10
The command will output exactly your expected result:
BEGIN line2 line3 END line4 line5 BEGIN line6 line7 ENDED END line8 END line9
Alternative State-Tracking Approach
If you prefer a more explicit state-based method, this version uses sed’s branch labels to track when we’re in the target range:
sed -n '/BEGIN/{:track; p; n; /END/{p; q}; b track}' logs.txt
/BEGIN/{:track; p; n}: WhenBEGINis found, set a labeltrack, print the line, then read the next line./END/{p; q}: If the new line containsEND, print it and quit.b track: If not, jump back to thetracklabel to keep printing lines until we hit the finalEND.
内容的提问来源于stack exchange,提问作者Dinesh Sonachalam

