텍스트 파일에서 문자열을 분할하는 빠른 방법은 무엇입니까?

텍스트 파일에서 문자열을 분할하는 빠른 방법은 무엇입니까?

string.txt와 lengths.txt라는 두 개의 텍스트 파일이 있습니다.

문자열.txt:

abcdefghijklmnopqrstuvwxyz

길이.txt

5
4
10
7

파일을 받고 싶어요

>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

저는 200자에서 56,000자 길이의 약 28,000개 항목을 작업하고 있습니다.

현재 나는 다음을 사용하고 있습니다 :

start=1
end=0
i=0
while read read_l
do
    let i=i+1
    let end=end+read_l
    echo -e ">Entry_$i" >>outfile.txt
    echo "$(cut -c$start-$end String.txt)" >>outfile.txt
    let start=start+read_l
    echo $i
done <lengths.txt

그러나 이는 매우 비효율적이다. 더 좋은 아이디어가 있나요?

답변1

일반적으로 말하면,텍스트를 처리하기 위해 쉘 루프를 사용하고 싶지 않습니다.. 여기서는 다음을 사용합니다 perl.

$ perl -lpe 'read STDIN,$_,$_; print ">Entry_" . ++$n' lengths.txt < string.txt
>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

그건하나(버퍼링을 사용하고 read한 번에 1바이트(또는 일반 파일의 경우 여러 바이트)를 읽는 쉘 명령보다 더 효율적) 두 파일을 모두 한 번만 읽는(메모리에 완전히 저장하지 않고) 명령은 다음과 같습니다. 쉘 루프에서 외부 명령을 실행하는 솔루션보다 훨씬 더 효율적입니다.

( -C숫자가 바이트가 아닌 현재 로케일의 문자여야 하는 경우 이 옵션을 추가하십시오. 예제의 ASCII 문자의 경우 차이가 없습니다.)

답변2

넌 할 수있어

{
  while read l<&3; do
    {
      head -c"$l"
      echo
    } 3<&-
  done 3<lengths.txt
} <String.txt

설명이 필요합니다.

주요 아이디어는 { head ; } <file과소평가된 @mikeserv에서 사용 및 파생되었습니다.답변. 그러나 이 경우에는 많은 head를 사용해야 하므로 while루프가 도입되고 파일 설명자가 약간 조정되어 head두 파일에 대한 입력이 전달됩니다(파일은 String.txt처리할 기본 파일로, 행은 length.txt인수로 전달됨). 옵션 -c). 아이디어는 또는 String.txt같은 명령이 호출될 때마다 검색할 필요가 없기 때문에 속도 이점이 있어야 한다는 것입니다. 각 반복 후에 개행 문자를 인쇄하세요.headcutecho

얼마나 빠른지 (만약 있다면) >Entry_i연습으로 줄 사이에 내용을 추가하는 것입니다.

답변3

배쉬, 버전 4

mapfile -t lengths <lengths.txt
string=$(< String.txt)
i=0 
n=0
for len in "${lengths[@]}"; do
    echo ">Entry_$((++n))"
    echo "${string:i:len}"
    ((i+=len))
done

산출

>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

답변4

무엇에 대해 awk?

다음 코드를 사용하여 라는 파일을 만듭니다 process.awk.

function idx(i1, v1, i2, v2)
{
     # numerical index comparison, ascending order
     return (i1 - i2)
}
FNR==NR { a[FNR]=$0; next }
{ i=1;PROCINFO["sorted_in"] = "idx";
        for (j in a) {
                print ">Entry"j;
                ms=substr($0, i,a[j])
                print ms
                i=i+length(ms)
        }
}

저장 및 실행awk -f process.awk lengths.txt string.txt

관련 정보