我可以使用什么来删除文件中每场比赛的当前和接下来的 20 行?

我可以使用什么来删除文件中每场比赛的当前和接下来的 20 行?

我有一个大文件(线程转储)。我有一堆已命名的线程my-thread-\d+,如果它们正在等待,我想从文件中删除该行和接下来的 20 行。

例如,我可能有一行看起来像:

"my-thread-1" #628 prio=5 os_prio=0 cpu=54888.61ms elapsed=194386.85s allocated=80325M defined_classes=4 tid=0x00007f406000c9d0 nid=0xb873 waiting on condition [0x00007f3faaeed000] 接下来是 20 行我不想要的行。

该模式将在文件中多次出现。我想对文件运行一个命令,每次删除 20 行my-thread-后跟waiting on conditon.

答案1

awk

awk '/my-thread-[[:digit:]]/ && /waiting on condition/ {skip = 21}
     skip-- <= 0'

如果在跳过的行内出现另一个等待线程,skip则重置为 21 并从那里再次跳过 21 行。

使用pcregrep(但忽略跳过行内进一步等待的线程):

pcregrep -Mv 'my-thread-\d.*waiting on condition(.*\n){20}'

答案2

在这种情况下,该grep实用程序几乎毫无用处,因为无法根据前一行的匹配来排除行(-A在 的某些实现中对可用选项的意义进行了某种否定grep)。

我将该请求解释为想要跳过匹配行和另外 20 行,而不查看这 20 行以查看模式是否再次匹配。

使用一种简单的方法sed是,每当输入中出现触发模式时,将以下 20 行附加到编辑缓冲区,然后将其全部删除。

sed '/^"my-thread-[[:digit:]]\{1,\}".*waiting on conditon/ { N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;d; }' file

我们可以对awk.

awk '/^"my-thread-[[:digit:]]+".*waiting on conditon/ { for (i=0; i<20; ++i) getline; next }; 1' file

或者,既然awk知道它在哪一行,我们可以向前跳过 20 行。

awk 'FNR < skip_to { next } /^"my-thread-[[:digit:]]+".*waiting on conditon/ { skip_to = FNR+21; next }; 1' file

在上面的代码中,FNR是包含当前文件中行号的特殊变量,而skip_to是当触发模式匹配时我们要跳到的行号。

答案3

awk '/my-thread-.*waiting on condition/{c=21} !(c&&c--)' file

例如:

$ seq 20 | awk '/3/{c=6} !(c&&c--)'
1
2
9
10
11
12
19
20

$ seq 20 | awk '/3/{c=11} !(c&&c--)'
1
2

使用 sed-或 awk-a-line-follow-a-matching-pattern 进行打印了解详细信息和其他相关习语。

相关内容