Разбить большую строку на подстроки - PullRequest
11 голосов
/ 27 сентября 2011

У меня есть огромная строка вроде:

ABCDEFGHIJKLM ...

и я хотел бы разбить его на подстроки длины 5 следующим образом:

> 1
ABCDE
> 2
BCDEF
> 3
CDEFG

[...]

ОБНОВЛЕНИЕ

Решение:
хорошо, спасибо вам, ребята, я смог найти способ сделать это быстро! Это мое решение, объединяющее несколько идей отсюда:

ул = "ABCDEFGHIJKLMNOP"
splitfive () {echo $ 1 | cut -c $ 2- | sed -r 's / (. {5}) / \ 1 \ n / g'; }
для ((i = 0; i <= 5; i ++)); сделать splitfive "$ str" $ i; сделано | grep -v "^ $" </p>

Ответы [ 9 ]

17 голосов
/ 27 сентября 2011
${string:position:length}

Извлекает символы $ длины из подстроки из $ string в $ position.

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

9 голосов
/ 27 сентября 2011

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 голосов
/ 27 сентября 2011

В 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
1 голос
/ 27 сентября 2011

sed может это сделать:

 sed -nr ':a;h;s/(.{5}).*/\1/p;g;s/.//;ta;' <<<"ABCDEFGHIJKLM" | # split string
     sed '=' | sed '1~2s/^/>/' # add line numbers and insert '>'
1 голос
/ 27 сентября 2011

... или используйте команду split:

$ ls

$ echo "abcdefghijklmnopqr" | split -b5

$ ls
xaa  xab  xac  xad

$ cat xaa
abcde

split также работает с файлами ...

1 голос
/ 27 сентября 2011

Будет ли sed делать это?:

$ sed 's/\(.....\)/\1\n/g' < filecontaininghugestring
1 голос
/ 27 сентября 2011
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, я действительно не знаю язык.

0 голосов
/ 08 ноября 2018

fold -w5 должен сделать свое дело.

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

Ура!

0 голосов
/ 30 октября 2013

Вы можете использовать cut и указать characters вместо fields, а затем изменить выходной разделитель на все, что вам нужно, например, новую строку :

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

output

ABCDE
FGHIJ
KLMNO

или

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

выход

ABCDE:FGHIJ:KLMNO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...