2014-04-08 134 views
2

我需要删除上面2行和下面4行,以'Possible'开头。这条线也应该被删除。我不习惯在终端工作,但似乎是我想要的解决方案是最直接的。grep:参数列表太长

的问题是,我的档案有超过70000行,它似乎是太多grep

$ grep -v "$(grep -E -a -B 2 -A 3 'Possible' structure)" structure >final 
-bash: /bin/grep: Argument list too long 

是否有任何其他的方式来做到这一点?输入文件的片段,其中一部分要被擦除:

gi|41|gb|JH9|.1(59-594) Length: 73 bp 
Type: Glu Anticodon: CTC at 33-35 (59424-59426) Score: 22.64 
Possible pseudogene: HMM Sc=43.51 Sec struct Sc=-20.87 
     * | * | * | * | * | * | * | 
Seq: GCCCGTTTGGCTCAGTGGAtAGAGCATCGGCCCTCAgACCGTAGGGtCCTGGGTTCAGTTCTGGTCAAGGGCA 
Str: >>>>.>...>>>>........<<<<.>>>>........<<<.<......>.>>.......<<.<..<.<<<<. 
+1

@Rubens:谢谢!看起来更体面 – Nelly

回答

1

你可以试试这个sed

sed 'N;/^[^\n]*\n[^\n]*$/N; /.*\n.*\n.*Possible/{$q;N;N;N;d};P;D;' structure > final 
+0

如果我理解你写的内容,{$ q; N; N; N; d}表示后面的3行被删除(N; N; N; d)??但是也可以计算可能的线,所以一条线停留。尽管如此,如果我添加一个N,则输出是完全不同的 – Nelly

+0

@Nelly,每个N都增加一行。在这种情况下,它将删除“2行+可能的行+ 3行”。我测试过,即使添加'N',它也能正常工作。 – sat

+0

@Nelly,试试这个:'sed'N;/^ [^ \ n] * \ n [^ \ n] * $/N; /.* \ n。* \ n。*可能/ {$ q; N; N; N; N; d}; P; D;''用于删除2行+可能行+4行。 – sat

3

我认为你应该把你的命令分成两个阶段。在第一阶段,你选择你不希望在输出中看到的字符串(内部grep)并将结果保存到文件中。在第二阶段,使用-f grep标志(-f允许在文件中指定模式而不是命令行)来检查输入。

4

的问题是,我的文件中有超过70000行,这似乎是 太多的grep:

没有,但事实是,grep -E -a -B 2 -A 3 'Possible' structure扩展到的东西,使参数列表太大。您可以使用工艺替代代替:

grep -v -f <(grep -E -a -B 2 -A 3 'Possible' structure) structure >final 
+0

虽然似乎适用于小文件,需要很长时间我的真实输入文件 – Nelly

1

我不认为你可以用grep来做到这一点。相反,我建议在awk这样做。

#!/usr/bin/awk -f 

{ 
    # Record the current line in an array 
    line[NR]=$0; 
} 

# If we saw "Possible" 3 lines ago, remove the last 5 lines from the array 
(NR-3) in line && line[NR-3]~/Possible/ { 
    for (i=5;i;i--) { 
    delete line[NR-i]; 
    } 
} 

# Print the last 5th line if it's still in the buffer, then remove it to save memory 
(NR-5) in line { 
    print line[NR-5]; 
    delete line[NR-5]; 
} 

# And print anything remaining in the buffer 
END { 
    for (i=NR-4;i<=NR;i++) { 
    if (i in line) { 
     print line[i]; 
    } 
    } 
} 

随着“shebang”在顶部,你可以使这个独立的脚本。或者如果你真的想要的话,你可以把它全部压缩到一个命令行上。

因为我们通过5行滑动窗口处理输入数据,处理任何长度的数据集(70000行,700万行,不管是什么)应该不成问题。

+0

+1;也许不是要求,但是你需要在行中使用'(NR-5)和'if(i in line)'来正确处理_empty_行。 – mklement0

+1

是的,你说得对,我没有正确处理空行。你的建议也很重要,因为引用一个数组元素的方式实际上使它存在*。奇怪的是,你的建议并不适合我,因为'(NR-5)in line'似乎即使在'NR == 3'时也评估为真。仍试图找出原因。 – ghoti

+0

OH。得到它了。我还需要更改第一个条件,因为仅仅测试针对'line [NR-3]'的正则表达式会导致数组元素存在。 – ghoti