stdin에서 읽지 않더라도 읽기 루프가 첫 번째 줄 이후에 중지됩니다.

stdin에서 읽지 않더라도 읽기 루프가 첫 번째 줄 이후에 중지됩니다.

testContains라는 파일이 있습니다.

test
test

이 명령을 실행 중입니다.

while read line
do
echo "$line"
done </tmp/test

이는 "test"를 두 번 출력해야 하지만 한 번만 출력합니다. 사용해도 while IFS= read -r line아무 것도 바뀌지 않습니다. 이를 해결하는 방법은 세 번째 빈 줄을 출력하는 것이지만, 상관없이 작동해야 합니다.

답변1

노력하다:

while IFS='' read -r line || [ "$line" ]

예, 표준 입력(stdin)에서 읽고 <teststdin으로 리디렉션됩니다.

아마도 일어나고 있는 일은 읽기가 텍스트 파일을 처리하도록 설계되었다는 것입니다.올바른 텍스트 파일은 개행 문자로 끝나야 합니다..

어떤 것을 만들어개행 문자의 파일 끝 결과가 매우 빠릅니다.:

[ -n "$(tail -c1 file)" ] && printf '\n' >>file 

그러나 파일이 누락된 경우 개행 문자를 추가하기 위해 파일을 편집할 수 없는 경우 해결책은 (추가로) 내용을 읽었는지 테스트하는 것입니다.

while read line || [ "$line" ]

이로 인해 읽기가 실패했지만(새 줄을 읽지 않고(기본값) 파일의 끝에 도달) 무언가를 읽는 경우( 에서 "$line") 루프가 실행됩니다.

개행 문자로 끝나는 파일이든 아니든 상관없이 잘 작동합니다.

아니요, a는 IFS='' read실제로 마지막 행 읽기에 (직접적으로) 영향을 미치지 않습니다 IFS=''(기본 IFS와 비교).[ㅏ]공백, 탭, 줄바꿈)은 분할에만 영향을 미칩니다.일부변수(선행 및/또는 후행 공백 제거에 영향을 미치는 경우 제외(IFS에 공백만 포함된 경우)[비])). 변수( )가 하나뿐이므로 "$line"분할을 수행할 필요가 없습니다.

읽기 옵션 -d(2.04부터 bash에 있음)도 도움이 되지 않습니다. 일치시킬 특정 "파일 끝" 문자는 없습니다(마지막 바이트는 임의의 문자일 수 있음).

남은 유일한 옵션은 다음과 같습니다.

  • 올바른 텍스트 파일이 되도록 파일을 복구하세요.
  • 변수로 읽어온 내용이 있는지 테스트합니다 line.

그러면 올바른 스크립트는 다음과 같습니다.

#!/bin/bash
while IFS='' read -r line || [ "$line" ]
do
    printf '%s\n' "$line"
done <test

IFS=''는 IFS의 비정상적인 값으로 인한 문제를 방지하는 데 사용됩니다.


[1][2]물론 IFS에 값이 있을 수 있다면 다른 많은 문자가 제거될 수도 있습니다. try ("x"로 끝나는 값의 경우)

printf "test\ntesx\ntest" | while IFS="x" read -r line || [ "$line" ]; do echo "$line"; done

아니요, zsh는 다른 작업을 수행합니다.

관련 정보