gpt4 book ai didi

string - 在 bash 或 sed 中逐行计算匹配前后的字符串长度

转载 作者:行者123 更新时间:2023-12-01 22:23:55 24 4
gpt4 key购买 nike

我有一个 DNA 序列的“测试”文件,每个序列都有一个标题或 ID,如下所示:

>new
ATCGGC
>two
ACGGCTGGG
>tre
ACAACGGTAGCTACTATACGGTCGTATTTTTT

我想在匹配给定字符串之前和之后打印每个连续字符串的长度,例如CGG

输出将如下所示:

>new
2 1
>two
1 5
>tre
4 11 11

或者可以只在每行的匹配前后设置字符长度。

2 1
1 5
4 11 11

我第一次尝试使用 sed 在找到 '>' 后打印下一行,然后找到“CGG”的每个 grep 匹配项的字节偏移量,我将使用它来转换为长度,但这产生了以下结果:

sed -n '/>/ {n;p}' test | grep -aob "CGG" 

2:CGG
8:CGG
21:CGG
35:CGG

本质上,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

awk -F CGG

使用“CGG”作为字段分隔符调用 awk。这会将每一行解析为一组字段,这些字段由字符串“CGG”的每次出现(如果有)分隔开。 “CGG”字符串本身既不包含在任何字段中,也不属于任何字段。

因此行ACAACGGTAGCTACTATACGGTCGTATTTTTT被解析为三个字段:ACAA , TAGCTACTATA , 和 TCGTATTTTTT ,在 awk 程序中表示为 $1 , $2 , 和 $3 , 分别。

'/^>/ {print; next}

这个模式/ Action 告诉 awk 如果该行以 > 开头打印该行并立即转到下一行输入,而不考虑 awk 程序中的任何其他模式或操作。

{for (i=1; i<=NF; ++i) {printf "%s%s", length($i), (i==NF)?"\n":" "}}

如果我们执行此操作,我们知道该行不是> 开头(往上看)。由于只有一个 Action 而没有模式,因此对于到达此处的每一行输入都会执行该 Action 。

for 循环遍历所有字段(NF 是一个特殊的 awk 变量,它包含当前行中的字段数)并打印它们的长度。通过检查我们是否到达了最后一个字段,我们知道是打印换行符还是只打印一个空格。

关于string - 在 bash 或 sed 中逐行计算匹配前后的字符串长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37997728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com