한 줄에 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운영.