대용량 텍스트 데이터 파일을 한 줄씩 읽고 싶습니다. 샘플 코드:
lines=0
while IFS=$' \t\n'
do
lines=$(($lines+1))
read val
echo "lines=$lines val=$val"
done < myfile
문제: 루프가 파일 끝까지 읽습니다!
$ wc -l myfile
41788 myfile
처음에는 모든 것이 잘 진행되고 데이터가 인쇄된 것을 볼 수 있지만 41788 이후에도 루프가 멈추지 않습니다. 카운터는 빈 줄에서 계속 실행되며 이를 중지하려면 CTRL-C'it를 눌러야 합니다.
데이터 파일을 확인했는데 특별한 것은 없습니다. size=5088370바이트, 필드는 탭으로 구분됩니다(1).
$ file myfile
myfile: ISO-8859 text, with CRLF line terminators
여기서 무슨 일이 일어나고 있는지에 대한 단서가 있습니까? 내가 놓친 게 무엇입니까?
(1) 이 필드는 실제로 로 읽혀지지만 read -a val
MCWE를 줄이기 위해 위의 단순화된 코드를 시도했습니다.
답변1
$' \t\n'
IFS 설정이 성공하는 한 루프가 실행된다는 뜻입니다 . 다음과 같아야 합니다.
while IFS=$' \t\n' read -r val
do
((lines++))
echo "lines=$lines val=$val"
done < myfile
의 기본값은 이렇게 설정 IFS
해야 하므로 설정이 중복될 수 있습니다. $' \t\n'
또한 나는 read
기본적으로 전체 줄을 읽는다고 생각하며, IFS를 그렇게 설정하더라도 $' '
여전히 전체 줄을 읽게 될 것이라고 생각합니다.
공백으로 구분 하려면 다음 스위치를 read
사용하면 됩니다 .-d
read -r -d' ' val
do
((lines++))
echo "lines=$lines val=$val"
done < myfile
이는 string 의 공백으로 구분된 각 문자열을 반복합니다 myfile
.