我遇到了一个非常简单的问题。我希望你能帮助我我有一个看起来像这样的大文件:
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;
}
}