如何提取PAT1与第3次出现的PAT2之间的文本行?
Hey there! Let's figure out how to get exactly the content you need. Your input is a single line where PAT1 appears once, and PAT2 shows up multiple times—you want everything from PAT1 up to (and including) the 3rd PAT2. The basic awk '/PAT1/PAT2/' command stops at the first PAT2, so we need a smarter approach.
Solution for Single-Line Input (Your Case)
Since your content is all in one line, we can use a non-greedy regular expression in awk to target the exact substring:
awk '{ match($0, /PAT1.*?PAT2.*?PAT2.*?PAT2/); print substr($0, RSTART, RLENGTH) }' your_file.txt
Let's break this down:
match($0, /PAT1.*?PAT2.*?PAT2.*?PAT2/): This regex looks forPAT1, then the shortest possible text until the firstPAT2, repeats that twice more to reach the 3rdPAT2. The.*?is key here—it's non-greedy, so it won't jump to the lastPAT2in the line.substr($0, RSTART, RLENGTH): Aftermatch()finds the target substring, it setsRSTARTto the start position andRLENGTHto the length of the match. We use these to extract and print the exact part we want.
When you run this on your sample input:
1 2 PAT1 3 4 PAT2 5 6 PAT2 7 PAT2 8 9 PAT2 10
You'll get your desired output:
PAT1 3 4 PAT2 5 6 PAT2 7 PAT2
Bonus: Solution for Multi-Line Input
If your content was spread across multiple lines (e.g., PAT1 on one line, PAT2 on separate lines), we'd use a flag-and-count approach instead:
awk '/PAT1/{flag=1} flag{print; if(/PAT2/) count++} count==3{exit}' your_file.txt
How this works:
/PAT1/{flag=1}: Flip a flag to start capturing content when we hitPAT1.flag{print; if(/PAT2/) count++}: Print every line while the flag is set, and increment a counter each time we seePAT2.count==3{exit}: Stop processing as soon as we hit the 3rdPAT2.
内容的提问来源于stack exchange,提问作者dbar

