使用sed或awk删除bash中与pattern不相邻的行

时间:2017-12-09 01:24:54

标签: bash awk sed grep

我需要删除任何不包围">"符号

以下是一些示例数据:

sample1.fasta
>R00003
ATCATACTACTACG
sample2.fasta
sample3.fasta
sample4.fasta
>R00003
ATACTACGTA
sample7.fasta
>R00003
ATGCATCAT
sample8.fasta
>R00003
AATCATCGACCT
sample9.fasta
sample10.fasta
>R00003
AGCATCTCAGTC

我尝试使用awk来帮助揭示问题:

awk '{/fasta/?f++:f=0} f==2' R3.fasta

返回:

sample3.fasta
sample10.fasta

这是诊断性的,因为它显示了重复的位置。但是,我想删除那些不在">"两边的符号。这不会删除它们,只会显示第二个。 我期望的结果是:

sample1.fasta
>R00003
ATCATACTACTACG
sample4.fasta
>R00003
ATACTACGTA
sample7.fasta
>R00003
ATGCATCAT
sample8.fasta
>R00003
AATCATCGACCT
sample10.fasta
>R0003
AGCATCTCAGTC

如果线条没有剥落">"符号已被删除

4 个答案:

答案 0 :(得分:1)

似乎普通的 grep 就足够了:

grep '^>' -C1 file | grep -v ^--$

首先在上面打印一行,在每行下面打一行,以>开头(使用上下文-C1),然后只过滤掉--插入的grep行将每个背景分开。

但如果您更喜欢 awk

awk '/^>/{print a ORS $0; getline; print} {a=$0}' file

将上一行保留在a中,当一行以>开头时,打印上一行(a),当前行和下一行(我们得到getline)。

答案 1 :(得分:0)

从示例中,您似乎需要所有非fasta线,而对于fasta线,您只需要下一个>之前的最后一个fasta文件。在这种情况下,请尝试:

$ awk 'f && !/fasta/{print f; f=""} /fasta/{f=$0; next} END{if(f)print f} 1' R3.fasta
sample1.fasta
>R00003
ATCATACTACTACG
sample4.fasta
>R00003
ATACTACGTA
sample7.fasta
>R00003
ATGCATCAT
sample8.fasta
>R00003
AATCATCGACCT
sample10.fasta
>R0003
AGCATCTCAGTC

如何运作

  1. f && !/fasta/{print f; f=""}

    如果设置变量f并且当前行不包含fasta,则打印f并删除其当前值。

  2. /fasta/{f=$0; next}

    如果当前行包含fasta,则将当前行保存到变量f,滑动其余命令,然后跳转到next行。

  3. END{if(f)print f}

    如果在我们到达文件末尾之后仍然将f设置为某个内容,则将其打印出来。

  4. 1

    对于所有其他行,请打印它们。

答案 2 :(得分:0)

另一个awk

$ awk '{if (/fasta/) f=$0; 
        else {if(f) print f; f=""; print}}' file

并不依赖于它们之间的行数。

答案 3 :(得分:0)

使用sed

sed ':A;/fasta$/!d;N;/\n>/!{s/.*\n//;bA};N' infile

sed '
:A              # label for jump
/fasta$/!d      # if the line end with fasta not delete
N               # add the next line in the pattern space
/\n>/!{         # if this new line don'\''t start with >
s/.*\n//        # delete it
bA}             # and jump to A
N               # else get the next line and print
' infile