You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在指定关键词后删除不含目标关键词的行及实操场景咨询

Solution to Your Text Processing Needs

Let's break down and solve your two text manipulation problems with practical, command-line tools that are commonly used for these tasks:

Problem 1: Delete all lines after keyword1 if keyword2 doesn't exist in the file

The core idea here is to first check if keyword2 exists in the file, then stop printing lines right after keyword1 only if keyword2 is missing. We can use awk to handle this logic smoothly, as it supports state tracking and array storage for lines.

Here's the awk command you can use:

BEGIN { found_keyword2 = 0 }
/keyword2/ { found_keyword2 = 1 }
{ lines[NR] = $0 }
END {
    for (i=1; i<=NR; i++) {
        print lines[i]
        if (lines[i] ~ /keyword1/ && !found_keyword2) {
            break
        }
    }
}

How it works:

  1. We start by initializing a flag found_keyword2 to 0 (false) in the BEGIN block.
  2. As we read each line, if we encounter keyword2, we set found_keyword2 to 1 (true).
  3. We store every line in an array lines indexed by line number (NR).
  4. In the END block, we loop through the stored lines:
    • Print each line until we hit keyword1.
    • If keyword2 was never found, we break the loop immediately after printing keyword1, effectively discarding all subsequent lines.
    • If keyword2 exists, we'll print all lines normally.

To run this on your file (replace your_file.txt with your actual filename):

awk -f script.awk your_file.txt

Or as a one-liner:

awk 'BEGIN { found_keyword2 = 0 } /keyword2/ { found_keyword2 = 1 } { lines[NR] = $0 } END { for (i=1; i<=NR; i++) { print lines[i]; if (lines[i] ~ /keyword1/ && !found_keyword2) break } }' your_file.txt

Problem 2: Delete lines without test1 after the /test1/end line in test_long_sentence.txt

For this task, we need to switch into a "filter mode" once we encounter the /test1/end line: before that line, print everything; after that line, only print lines that contain test1. Again, awk provides a straightforward way to implement this with a flag.

/\/test1\/end/ { flag=1; print; next }
flag == 1 { if (/test1/) print; next }
1

How it works:

  1. When we match the /test1/end line, we set the flag to 1, print the line itself, and use next to skip further processing for this line.
  2. Once flag is 1 (meaning we're after the /test1/end line), we only print the line if it contains test1; otherwise, we skip it.
  3. The final 1 is a shorthand in awk that means "print the current line" — this applies to all lines before the /test1/end line, since the flag is still 0.

Run it directly on your file:

awk '/\/test1\/end/ { flag=1; print; next } flag == 1 { if (/test1/) print; next } 1' test_long_sentence.txt

Alternative with sed:

If you prefer sed, here's a command that achieves the same result:

'/\/test1\/end/{p;:a;n;/test1/!d;ba}' test_long_sentence.txt

How the sed command works:

  1. When /test1/end is matched, we first print the line (p).
  2. We define a label :a, then read the next line (n).
  3. If the line doesn't contain test1, we delete it (d) and jump back to label a to process the next line.
  4. If the line does contain test1, it's printed automatically (since we don't delete it) and we jump back to a to continue filtering.

内容的提问来源于stack exchange,提问作者Jojoleo

火山引擎 最新活动