将一个大字符串拆分为子字符串

时间:2014-09-04 14:37:01

标签: string bash awk

我有这个文件:

>first
GTGAAGTGCGGCACCCCGTAGGTCAGACAAGGCGGTCACGCCGCATCCGACATCCAACGCCCGAGCCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC
>second
CGGTAAT

我的预期输出是:

>first
GTGAAGTGCGGCACCCCGTAGGTCAGACAAGGCGGTCACGCCGCATCCGACATCCAACGC
CCCGAGCCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAACC
>second
CGGTAAT

说明:如果(该行以'>'开头)打印​​;否则,如果字符串的长度大于60,则将字符串拆分为60的子字符串。

我的想法在awk中是这样的,但也欢迎bash解决方案:

gawk '/^>/ {print;next;} {len=length; if(len>60){DO SOMETHING HERE (LOOP?)} else {print}}'

任何帮助都将非常感谢! 感谢

4 个答案:

答案 0 :(得分:5)

您可以在BASH循环中使用内置的fold实用程序:

while read -r f; do
    [[ "$f" == '>'* ]] && echo "$f" || echo "$f" | fold -w 60
done < file

答案 1 :(得分:4)

使用awk即可:

$ awk '!/^>/&&length($0)%60{gsub(/.{60}/,"&\n")}1' file
>first
GTGAAGTGCGGCACCCCGTAGGTCAGACAAGGCGGTCACGCCGCATCCGACATCCAACGC
CCGAGCCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAACC
>second
CGGTAAT

注意:如果您使用的是GNU awk v3.x,请添加--re-intervalawk --re-interval '..' file)。对于GNU awk v4或更高版本以及BSD awk,它不是必需的。

答案 2 :(得分:1)

这个awk怎么样?

awk -v FS= 
    '{for (i=0;i<=NF/60;i++) {
          for (j=1;j<=60;j++)
               printf "%s", $(i*60 +j)
          print ""
          }
     }' file

见输出:

$ awk -v FS= '{for (i=0;i<=NF/60;i++) {for (j=1;j<=60;j++) printf "%s", $(i*60 +j); print ""}}' file
>first
GTGAAGTGCGGCACCCCGTAGGTCAGACAAGGCGGTCACGCCGCATCCGACATCCAACGC
CCGAGCCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAACC
>second
CGGTAAT

您可以使用以下内容明确>条件:

awk -v FS= '/^>/ {print; next} {for (i=0;i<=NF/60;i++) {for (j=1;j<=60;j++) printf "%s", $(i*60 +j); print ""}}' file

解释

  • -v FS=将字段分隔符设置为空,以便每个字符都是一个字段。
  • '/^>/ {print; next}如果该行以>开头,请将其打印并转到下一行。
  • {for (i=0;i<=NF/60;i++) {for (j=1;j<=60;j++) printf "%s", $(i*60 +j); print ""}}在其余案例中,以60个字符为单位循环,打印所有这些字符,然后打印一个新行,直到到达行尾。

答案 3 :(得分:0)

避免完全分割线条,只需手动进行子串打印。

awk -v FS='\n' '!/^>/ {for (i=0; i<(length($0)/60); i++) {print substr($0, i*60, 60)}; next}7'