나는 Bash에서 N자마다 파일을 읽는 여러 가지 방법을 이미 알고 있습니다.
LC_ALL=C
while read -n100 character; do
echo "$character"
done < <(cat "$@" | tr -d '\n')
echo "$character
그러나 이것이 작동하는 동안 Bash에서나 posix/unix 도구를 사용하여 이 작업을 수행하는 더 빠른 방법을 알고 싶습니다.
이 작업을 더 빠르게 수행할 수 있는 다른 방법이 있나요?
답변1
복사AdminBee 결과약간 더 간단한 코드를 사용하십시오.
입력 데이터는 해당 데이터와 동일합니다.
12345678901234
567890123
4567890123456789012
34567890123
10부터 시작하여 10자마다:
$ fold -w 1 file | awk 'NR % 10 == 0'
0
0
0
0
0
동일하지만 1부터 시작합니다.
$ fold -w 1 file | awk 'NR % 10 == 1'
1
1
1
1
1
1
동일하지만 2부터 시작합니다.
$ fold -w 1 file | awk 'NR % 10 == 2'
2
2
2
2
2
2
성능 측면에서 이는 awk
AdminBee의 솔루션과 비슷하지만 큰 입력("큰 입력" == 위의 테스트 데이터가 여러 번 반복됨)에서는 약간 더 빠릅니다.
fold -w 1
입력의 각 문자에 대해 한 줄을 생성하고 줄 바꿈을 삭제합니다. 사용된 두 명령은 모두 표준 POSIX 유틸리티입니다.
답변2
"null 필드 구분 기호" 확장 덕분에 awk
모든 구현이 아닌 많은 구현에서 작동하는 이 솔루션을 사용해 보세요.awk
awk -F "" -v l=100 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==0) {print $i; last=i}};\
if (last) {carry=NF-last} else {carry+=(NF-l)}}' inputfile.txt
이는 각 문자를 단일 필드( -F ""
)로 처리하고 필드 번호 모듈로 "건너뛰기 길이" l
(귀하의 경우 100)가 0인 필드만 인쇄하며 이월을 고려하지만 개행은 무시합니다.
1부터 세기 시작하므로 첫 번째 문자는아니요읽다. 당신은 그것을 사용할 수 있습니다
awk -F "" -v l=10 -v ofs=1 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==ofs) {print $i; last=i}};\
if (last) {carry=NF-last+ofs} else {carry+=(NF-l)}}' inputfile.txt
오프셋을 조정하여 ofs
.
테스트 케이스
Linux 시스템에서 gawk
, 및 를 사용하여 mawk
테스트되었습니다 .nawk
- 입력 파일
12345678901234 567890123 4567890123456789012 34567890123
- "10번째 문자부터 10마다" 출력
$ awk -F "" -v l=10 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==0) {print $i; last=i}}; if (last) {carry=NF-last} else {carry+=(NF-l)}}' testfile.txt 0 0 0 0 0
- "첫 번째 문자부터 시작하여 10마다"를 출력합니다.
$ awk -F "" -v l=10 -v ofs=1 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==ofs) {print $i; last=i}}; if (last) {carry=NF-last+ofs} else {carry+=(NF-l)}}' testfile.txt 1 1 1 1 1 1