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

时间:2011-09-27 11:08:36

标签: string bash shell

我有一个巨大的字符串:

  

ABCDEFGHIJKLM ......

我希望以这种方式将其拆分为长度为5的子串:

  

→1个
  ABCDE
  →2
  BCDEF
  →3
  CDEFG

     

[...]

更新

解决方案:
好的,多亏你们,我能找到快速做到这一点的方法!这是我的解决方案,结合了这里的一些想法:

  

STR = “ABCDEFGHIJKLMNOP”
  splitfive(){echo $ 1 | cut -c $ 2- | sed -r's /(。{5})/ \ 1 \ n / g'; }
  for((i = 0; i <= 5; i ++)); splitfive“$ str”$ i;完成| grep -v“^ $”

9 个答案:

答案 0 :(得分:17)

${string:position:length}

在$ position处从$ string中提取子字符串的$ length字符。

stringZ=abcABC123ABCabc
#       0123456789.....
#       0-based indexing.

echo ${stringZ:0}                            # abcABC123ABCabc
echo ${stringZ:1}                            # bcABC123ABCabc
echo ${stringZ:7}                            # 23ABCabc

echo ${stringZ:0:5}                          # abcAB
                                             # Five characters of substring.

然后使用循环遍历并向该位置添加1以提取长度为5的每个子字符串。

for i in seq 0 ${#stringZ}; do
    echo ${stringZ:$i:5}
done

全部来自Bash string manipulation

答案 1 :(得分:9)

sed可以一次性完成:

kent$  echo "abcdefghijklmnopqr"|sed -r 's/(.{5})/\1 /g'
abcde fghij klmno pqr

取决于您的需求:

kent$  echo "abcdefghijklmnopqr"|sed -r 's/(.{5})/\1\n/g' 
abcde
fghij
klmno
pqr

<强>更新

我认为这只是简单的分裂字符串问题,没有仔细阅读问题。现在它应该给你需要的东西:

还是一枪,但这次是awk:

kent$  echo "abcdefghijklmnopqr"|awk '{while(length($0)>=5){print substr($0,1,5);gsub(/^./,"")}}'

abcde
bcdef
cdefg
defgh
efghi
fghij
ghijk
hijkl
ijklm
jklmn
klmno
lmnop
mnopq
nopqr

答案 2 :(得分:2)

在bash中:

s=ABCDEFGHIJ
for (( i=0; i < ${#s}-4; i++ )); do 
  printf ">%d\n%s\n" $((i+1)) ${s:$i:5}
done

输出

>1
ABCDE
>2
BCDEF
>3
CDEFG
>4
DEFGH
>5
EFGHI
>6
FGHIJ

答案 3 :(得分:1)

str=ABCDEFGHIJKLM
splitfive(){ echo "${1:$2:5}" ; }
for (( i=0 ; i < ${#str} ; i++ )) ; do splitfive "$str" $i ; done

或者,也许你想用结果做一些更聪明的事情

#!/usr/bin/env bash

splitstr(){
    printf '%s\n' "${1:$2:$3}"
}

n=$1
offset=$2

declare -a by_fives

while IFS= read -r str ; do
    for (( i=0 ; i < ${#str} ; i++ )) ; do
            by_fives=("${by_fives[@]}" "$(splitstr "$str" $i $n)")
    done
done

echo ${by_fives[$offset]}

然后叫它

$ split-by 5 2 <<<"ABCDEFGHIJKLM"
CDEFG

你可以从那里进行调整。

编辑:C中的普通版本,用于性能比较:

#include <stdio.h>

int main(void){
    FILE* f;
    int n=0;
    char five[6];

    five[5] = '\0';

    f = fopen("inputfile", "r");

    if(f!=0){
            fread(&five, sizeof(char), 5, f);
            while(!feof(f)){
                    printf("%s\n", five);
                    fseek(f, ++n, SEEK_SET);

                    fread(&five, sizeof(char), 5, f);
            }
    }

    return 0;
}

原谅我的坏C,我真的不懂语言。

答案 4 :(得分:1)

sed会这样做吗?:

$ sed 's/\(.....\)/\1\n/g' < filecontaininghugestring

答案 5 :(得分:1)

...或使用split命令:

$ ls

$ echo "abcdefghijklmnopqr" | split -b5

$ ls
xaa  xab  xac  xad

$ cat xaa
abcde

split也对文件进行操作......

答案 6 :(得分:1)

sed可以做到:

 sed -nr ':a;h;s/(.{5}).*/\1/p;g;s/.//;ta;' <<<"ABCDEFGHIJKLM" | # split string
     sed '=' | sed '1~2s/^/>/' # add line numbers and insert '>'

答案 7 :(得分:0)

您可以使用cut并指定characters而不是fields,然后将输出分隔符更改为您需要的内容,例如新行

echo "ABCDEFGHIJKLMNOP" | cut --output-delimiter=$'\n' -c1-5,6-10,11-15

输出

ABCDE
FGHIJ
KLMNO

echo "ABCDEFGHIJKLMNOP" | cut --output-delimiter=$':' -c1-5,6-10,11-15 

输出

ABCDE:FGHIJ:KLMNO

答案 8 :(得分:0)

fold -w5应该可以解决问题。

$ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | fold -w5
ABCDE
FGHIJ
KLMNO
PQRST
UVWXY
Z

干杯!