LP_*_*640 1 string bash awk sed
我有一个DNA测试文件'test',每个都有一个标题或ID,如下所示:
>new
ATCGGC
>two
ACGGCTGGG
>tre
ACAACGGTAGCTACTATACGGTCGTATTTTTT
Run Code Online (Sandbox Code Playgroud)
我想在匹配之前和之后打印每个连续字符串的长度,例如 CGG
输出将如下所示:
>new
2 1
>two
1 5
>tre
4 11 11
Run Code Online (Sandbox Code Playgroud)
或者只能在每行的匹配之前和之后具有字符长度.
2 1
1 5
4 11 11
Run Code Online (Sandbox Code Playgroud)
我第一次尝试使用sed在找到'>'后打印下一行,然后找到每个grep匹配"CGG"的字节偏移量,我将用它来转换为长度,但这产生了以下结果:
sed -n '/>/ {n;p}' test | grep -aob "CGG"
2:CGG
8:CGG
21:CGG
35:CGG
Run Code Online (Sandbox Code Playgroud)
从本质上讲,grep是为每个匹配打印字节偏移量,向上计数,而我希望每行独立的字节偏移量(即在每行之后重置).
我想我也需要使用sed进行搜索,因为它逐行操作,但我不知道如何抵消给定字符串中的字节偏移或字符.
任何帮助将非常感激.
通过使用给定的字符串作为awk中的字段分隔符,它就像迭代每行上的字段并打印它们的长度一样简单.(从>我们开始的行开始按原样打印.)
这为您的样本数据提供了所需的输出,但您可能希望检查边缘情况,例如开头CGG,结尾CGG,仅包含CGG等.
$ awk -F CGG '/^>/ {print; next} {for (i=1; i<=NF; ++i) {printf "%s%s", length($i), (i==NF)?"\n":" "}}' file.txt
>new
2 1
>two
1 5
>tre
4 11 11
Run Code Online (Sandbox Code Playgroud)
awk -F CGG
使用"CGG"作为字段分隔符调用awk.这会将每一行解析为一组字段,这些字段由字符串"CGG"的每个(如果有)出现."CGG"字符串本身既不包含在任何字段中,也不包含在任何字段中.
因此,该线ACAACGGTAGCTACTATACGGTCGTATTTTTT被解析成三个字段:ACAA,TAGCTACTATA,和TCGTATTTTTT,通过在AWK程序表示$1,$2和$3分别.
'/ ^>/{print; 下一个}
这个模式/动作告诉awk如果行开始>打印行并立即进入下一行输入,而不考虑awk程序中的任何进一步的模式或动作.
{for(i = 1; i <= NF; ++ i){printf"%s%s",length($ i),(i == NF)?"\n":""}}
如果我们到达这个动作,我们知道行并没有下手>(见上文).由于只有一个动作而没有模式,因此对于到达此处的每一行输入执行动作.
for循环遍历所有字段(NF是一个特殊的awk变量,包含当前行中的字段数)并打印它们的长度.通过检查我们是否到达最后一个字段,我们知道是打印换行还是仅打印一个空格.
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |