Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在bash或sed中逐行计算匹配前后的字符串长度_String_Bash_Awk_Sed - Fatal编程技术网

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

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 我的第一次尝试是在找到

我有一个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'/^>/{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”,当它们应该为零时。我想我需要查看示例输入和输出以真正理解最后一个问题——如果您还没有找到解决方案,也许最好为其打开一个新问题。