한 줄 안의 자릿수를 세어 파일을 분할하는 방법은 무엇입니까?

한 줄 안의 자릿수를 세어 파일을 분할하는 방법은 무엇입니까?

한 줄에 45000자를 포함하는 파일이 있고 줄의 특정 문자 수를 기준으로 원본 파일을 분할하고 싶습니다. 작은 예로, 입력 파일은 다음과 같습니다.

입력.txt:

123394531112334455938383726644600000111234499922281133
234442221117273747474747474729292921111098887777772235
231112233647474838389292121037549284753930837475111013

각 줄에는 54자리 숫자가 있습니다. 처음 10자리는 별도의 파일로, 11~24번째 자리는 다른 파일로 만들고 싶습니다. 비트 25-32는 또 다른 파일이고, 비트 33-50은 마지막 파일입니다. 예:

out1.txt(1-10)

1233945311
2344422211
2311122336

out2.txt(11-24)

 12334455938383
 17273747474747
 47474838389292

out3.txt(25-32)

72664460
47472929
12103754

out4.txt (33-54)

0000111234499922281133
2921111098887777772235
9284753930837475111013

어떤 제안이 있으십니까?

답변1

cut여러 번 호출 할 수 있습니다 .

cut -c 1-10  < file > out1.txt
cut -c 11-24 < file > out2.txt
cut -c 25-32 < file > out3.txt
cut -c 33-54 < file > out4.txt

(현재 버전의 GNU는 cut멀티바이트 문자를 지원하지 않습니다(입력의 ASCII 십진수에는 문제가 되지 않습니다).

아니면 awk한숨에:

awk '{
  print substr($0, 1,  10) > "out1.txt"
  print substr($0, 11, 14) > "out2.txt"
  print substr($0, 25, 8 ) > "out3.txt"
  print substr($0, 33, 22) > "out4.txt"}' < file

awk(현재 버전의 일부 구현은 mawk멀티바이트 문자를 지원하지 않습니다(ASCII 10진수에서는 문제가 되지 않음).)

GNU를 사용하면 awk다음도 수행할 수 있습니다.

awk -v FIELDWIDTHS='10 14 8 22' '
  {for (i = 1; i <= NF; i++) print $i > "out" i ".txt"}' < file

답변2

읽기 및 매개변수 대체/확장/분할을 사용하여 Bash를 사용하여 이를 수행할 수 있습니다. 형식은 ${PARAMETER:OFFSET:LENGTH}이며, 여기서 OFFSET은 0부터 시작됩니다. 예를 들어 다음 파일을 "split"로 저장하고 다음과 같이 각 줄을 읽습니다.

#!/usr/bin/env bash

# Usage: ./split "data.txt"

while IFS= read -r line
do
    printf '%s\n' "${line:0:10}"  >&3  #  1-10
    printf '%s\n' "${line:10:14}" >&4  # 11-24
    printf '%s\n' "${line:24:8}"  >&5  # 25-32
    printf '%s\n' "${line:32:22}" >&6  # 33-54
done < "$1" 3> output01.txt 4> output02.txt 5> output03.txt 6> output04.txt

# end file

물론 위의 위치를 ​​약간 조정해야 할 수도 있지만 이 모델을 다양한 유형의 파일 처리에 사용할 수 있습니다. 위의 위치는 원하는 출력을 생성합니다. 매개변수 확장에 대한 좋은 참고 자료는 다음에서 찾을 수 있습니다.bash-hackers.org


포스트스크립트로서 권장되는 개선 사항(설명 참조)을 통합한 후 대용량 파일의 경우 Bash 접근 방식은 CPU 시간 및 CPU 리소스 측면에서 효율적이지 않다는 점을 명심하세요. 이 진술을 수량화하기 위해 아래에 간단한 비교를 준비했습니다. 먼저 시작 기사 데이터의 길이가 300,000줄(16500000바이트)인 테스트 파일(bigsplit.txt)을 만듭니다. 그런 다음 비교나뉘다,자르다그리고,안에자르다그리고구현은 동일합니다스티븐 차제라스버전. 초 단위의 CPU 시간은 시스템 및 사용자 CPU 시간의 합이며, RAM은 사용된 최대값입니다.

$ stat -c %s bigsplit.txt && wc -l bigsplit.txt 
16500000
300000 bigsplit.txt

$ ./benchmark ./split bigsplit.txt 

CPU TIME AND RESOURCE USAGE OF './split bigsplit.txt'
VALUES ARE THE AVERAGE OF ( 10 ) TRIALS

CPU, sec :   88.41
CPU, pct :   99.00
RAM, kb  : 1494.40

$ ./benchmark ./cut bigsplit.txt 

CPU TIME AND RESOURCE USAGE OF './cut bigsplit.txt'
VALUES ARE THE AVERAGE OF ( 10 ) TRIALS

CPU, sec :    0.86
CPU, pct :   99.00
RAM, kb  :  683.60

$ ./benchmark ./awk bigsplit.txt

CPU TIME AND RESOURCE USAGE OF './awk bigsplit.txt'
VALUES ARE THE AVERAGE OF ( 10 ) TRIALS

CPU, sec :    1.19
CPU, pct :   99.00
RAM, kb  : 1215.60

비교는 다음과 같습니다. 최고의 성능,자르다에는 값 1이 할당됩니다.

                             RELATIVE PERFORMANCE 

                                    CPU Secs     RAM kb
                                    --------     ------
                    cut                    1          1
                    awk                  1.4        1.8
                    split (Bash)       102.8        2.2

이 경우에는 의심의 여지가 없습니다.자르다더 큰 파일을 위한 도구입니다. Bash의 대략적인 예비 테스트나뉘다위에,파일에서 읽을 때루프에는 CPU 시간이 약 5초 걸렸습니다.매개변수 확장약 8초 정도 소요되며 나머지는 과 관련이 있다고 할 수 있습니다.파일로 printf운영.

관련 정보