如何根据特定列字段中出现PATTERN的连续次数来选择行



我遇到了一个非常简单的问题。我希望你能帮助我我有一个看起来像这样的大文件:

32 Q beta
33 S beta
34 A nb
35 T nb
36 G nb
37 T nb
38 K nb
39 T nb
40 D nb
41 T beta
42 P beta
43 I nb
44 Q nb
45 K nb
46 V nb
50 I beta
51 S beta
52 V beta
53 V beta
54 T beta

它总是以一行开始,其中$3="0";β";。我只想保存包含特定次数(<=5(的模式"的行;非β;并且仅复制第3列等于"0"的前一行/后一行;β;(尽管有这些行的编号(。

因此输出为:

41 T beta
42 P beta
43 I nb
44 Q nb
45 K nb
46 V nb
50 I beta
51 S beta
52 V beta
53 V beta
54 T beta

你能帮帮我吗?感谢所有

以下将执行请求的操作

grep -zPo '(^|n)(S+sS+sbetan)+(S+sS+s(?!beta).*n){1,4}(S+sS+sbetan)+' file.txt  | tr '' 'n'

然而,可能并没有达到你的预期:当许多(<=5(非贝塔模式被贝塔线分隔时,由于贝塔线已经被消耗,下一个匹配将找不到。模式应该根据实际需要进行更改。

Perl来拯救!

只要我能够理解需求并测试它,下面的perl脚本似乎可以工作

  • -n逐行读取输入并执行每行的脚本

  • -l从输入中删除换行并将它们添加到输出

  • -a将空白上的每一行拆分为@F数组

  • 变量CCD_ 4用于指示我们要在打印的部分之后打印贝塔。

  • 变量$count决定一个区段具有的行数

  • 变量CCD_ 6包含前一行的第三列。

  • 阵列CCD_ 7累积我们稍后可能打印的行。

#!/usr/bin/perl -lan
if ($F[2] eq 'beta') {
if ($printing) {
print;
} elsif ($previous eq 'beta') {
push @buffer, $_;
} elsif ($count && $count <= 5) {
print for @buffer, $_;
@buffer = ();
$printing = 1;
} else {
@buffer = $_;
}
} else {
$printing = 0;
if ($previous eq $F[2]) {
++$count;
push @buffer, $_;
} elsif ($previous eq 'beta') {
$count = 1;
push @buffer, $_;
} elsif ($count <= 5) {
print for @buffer;
@buffer = $_;
$count = 1;
} else {
@buffer = $_;
$count = 1;
}
}
$previous = $F[2];
END {
if ($count <= 5) {
print for @buffer;
}
}

相关内容

  • 没有找到相关文章

最新更新