String 在bash或sed中逐行计算匹配前后的字符串长度
我有一个DNA序列的“测试”文件,每个文件都有一个标题或ID,如下所示:String 在bash或sed中逐行计算匹配前后的字符串长度,string,bash,awk,sed,String,Bash,Awk,Sed,我有一个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 我的第一次尝试是在找到
>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'/^>/{print;next}{for(i=1;i/{print;next}
此模式/操作告诉awk,如果该行以
开头,则打印该行并立即转到下一行输入,而不考虑awk程序中的任何其他模式或操作
{for(i=1;i
(见上文)。由于只有一个操作而没有模式,因此对到达此处的每一行输入都执行该操作
for循环遍历所有字段(
NF
是一个特殊的awk变量,包含当前行中的字段数)并打印它们的长度。通过检查是否已到达最后一个字段,我们知道是打印换行符还是仅打印空格。在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'/^>/{print;next}{for(i=1;i/{print;next}
此模式/操作告诉awk,如果该行以
开头,则打印该行并立即转到下一行输入,而不考虑awk程序中的任何其他模式或操作
{for(i=1;i
(见上文)。由于只有一个操作而没有模式,因此对到达此处的每一行输入都执行该操作
for循环遍历所有字段(
NF
是一个特殊的awk变量,包含当前行中的字段数)并打印它们的长度。通过检查我们是否到达最后一个字段,我们知道是打印换行符还是只打印空格。这太棒了。你能解释一下它是如何工作的吗?当然,很高兴它能帮上忙——请参阅补充说明。最后一个问题……假设该模式实际上是“CGGAAA”我想在这个匹配模式CGG AAA的中间分离/分裂,将CGG添加到字符之前和AAA之后。这样做容易吗?我想我可以简单地为每个字段添加三个数:代码>长度($i)。+3,没有匹配的行将是+3,结束匹配将是“3”,当它们应该为零时。我想我需要查看示例输入和输出来真正理解最后一个问题——如果你还没有找到解决方案,也许最好为它打开一个新问题。这太棒了。你能提供一点解释吗关于它是如何工作的?当然,很高兴它有帮助---见补充说明。最后一个问题…假设该模式实际上是“CGGAAA”我想在这个匹配模式CGG AAA的中间分离/分裂,将CGG添加到字符之前和AAA之后。这样做容易吗?我想我可以简单地为每个字段添加三个数:代码>长度($i)。+3,没有匹配项的贯穿行将为+3,结束匹配项将为“3”,当它们应该为零时。我想我需要查看示例输入和输出以真正理解最后一个问题——如果您还没有找到解决方案,也许最好为其打开一个新问题。