유닉스 명령을 사용하여 텍스트 파일의 각 줄에있는 문자 수를 인쇄하고 싶습니다. powershell로 간단하다는 것을 알고 있습니다.
gc abc.txt | % {$_.length}
하지만 유닉스 명령이 필요합니다.
답변:
Awk를 사용하십시오.
awk '{ print length }' abc.txt
while IFS= read -r line; do echo ${#line}; done < abc.txt
POSIX이므로 모든 곳에서 작동합니다.
편집 : William이 제안한대로 -r을 추가했습니다.
편집 : 유니 코드 처리에주의하십시오. 로케일이 올바르게 설정된 Bash 및 zsh는 코드 포인트 수를 표시하지만 dash는 바이트를 표시하므로 쉘이 수행하는 작업을 확인해야합니다. 그리고 어쨌든 유니 코드에는 길이에 대한 다른 많은 정의가 있으므로 실제로 원하는 것에 따라 다릅니다.
편집 : IFS=
앞뒤 공백을 잃지 않도록 접두어를 붙입니다 .
IFS=
에 설정 하십시오 read
. 그래서 IFS= read -r
. to do word splitting을 read
사용하고 IFS
, 모든 분할 단어가 사용 가능한 하나의 변수 ( line
)에 다시 붙여 넣어 지더라도 원래의 모든 구분 문자와 함께 다시 붙여 넣어 지거나 잠재적으로 다른 하나만 붙여진다는 보장은 없습니다. 하나. 예를 들어, 기본 IFS를 사용하면 줄 foo bar
이 foo bar
으로 바뀌어 7 개의 공백이 손실 될 수 있습니다. (이 주석의 예제 문자열에서 Stack Overflow가 인접한 공백을 잃어버린 것과 같습니다).
IFS
설정되어야하지만, 그렇지 않을 때의 문제는 더 미묘합니다.
위에 나열된 다른 답변을 시도했지만 대용량 파일을 다룰 때 특히 한 줄의 크기가 사용 가능한 RAM의 1/4 이상을 차지하면 적절한 솔루션과는 거리가 멀습니다.
bash와 awk 모두이 문제에 대해서는 필요하지 않지만 전체 라인을 슬러 핑합니다. 줄이 너무 길면 메모리가 충분하더라도 Bash는 오류가 발생합니다.
저는 매우 간단하고 최적화되지 않은 파이썬 스크립트를 구현했습니다.이 스크립트는 대용량 파일 (한 줄에 최대 4GB)로 테스트 할 때 소리가 나지 않으며 주어진 것보다 훨씬 더 나은 솔루션입니다.
이것이 프로덕션에 시간이 중요한 코드 인 경우 C로 아이디어를 다시 작성하거나 읽기 호출에서 더 나은 최적화를 수행 할 수 있습니다 (한 번에 한 바이트 만 읽는 대신), 이것이 실제로 병목 현상인지 테스트 한 후.
코드는 줄 바꿈 문자가 Unix에서는 좋은 가정이지만 Mac OS / Windows에서는 YMMV라고 가정합니다. 마지막 줄 문자 수를 간과하지 않도록 파일이 줄 바꿈으로 끝나는 지 확인하십시오.
from sys import stdin, exit
counter = 0
while True:
byte = stdin.buffer.read(1)
counter += 1
if not byte:
exit()
if byte == b'\x0a':
print(counter-1)
counter = 0