이 "while" 루프가 마지막 줄을 인식하지 못하는 이유는 무엇입니까?

이 "while" 루프가 마지막 줄을 인식하지 못하는 이유는 무엇입니까?

우리는 다음 스크립트를 사용합니다:

more test.sh
#!/bin/bash

while read -r line
do

echo $line

done < /tmp/file

파일은 다음과 같습니다.

kafka-broker,log.retention.hours,12
kafka-broker,default.replication.factor,2
fefolp-defaults,fefolp.history.fs.cleaner.interval,1d
fefolp-defaults,fefolp.history.fs.cleaner.maxAge,2d
fefolp-env,fefolp_daemon_memory,10000
blo-site,blo.nodemanager.localizer.cache.target-size-mb,10240
blo-site,blo.nodemanager.localizer.cache.cleanup.interval-ms,300000
ams-env,metrics_collector_heapsize,512
fefolp,hbase_master_heapsize,1408
fefolp,hbase_regionserver_heapsize,512
fefolp,hbase_master_xmn_size,192
core-site,blolp.proxyuser.ambari.hosts,*
core-site,Hadoop.proxyuser.root.groups,*
core-site,Hadoop.proxyuser.root.hosts,*
blo-site,blo.scheduler.minimum-allocation-mb,1024
blolp-env,fefolp_heapsize,4096

참고 - 마지막 줄 다음에는 공백이 없습니다!

그러나 스크립트는 다음 줄만 인쇄합니다(마지막 줄 제외).

./test.sh
kafka-broker,log.retention.hours,12
kafka-broker,default.replication.factor,2
fefolp-defaults,fefolp.history.fs.cleaner.interval,1d
fefolp-defaults,fefolp.history.fs.cleaner.maxAge,2d
fefolp-env,fefolp_daemon_memory,10000
blo-site,blo.nodemanager.localizer.cache.target-size-mb,140
blo-site,blo.nodemanager.localizer.cache.cleanup.interval-ms,300
ams-env,metrics_collector_heapsize,51
fefolp,hbase_master_heapsize,1408
fefolp,hbase_regionserver_heapsize,542
fefolp,hbase_master_xmn_size,19
core-site,blolp.proxyuser.ambari.hosts,*
core-site,Hadoop.proxyuser.root.groups,*
core-site,Hadoop.proxyuser.root.hosts,*
blo-site,blo.scheduler.minimum-allocation-mb,1024

왜 이런 일이 발생합니까?

답변1

입력 텍스트의 마지막 줄에 불완전한 줄이 있습니다. 마지막 줄은 개행 문자로 끝나지 않습니다.

while IFS= read -r line || [ -n "$line" ]; do
    printf '%s\n' "$line"
done <file

위의 루프는 호출된 파일에서 수정되지 않은 행을 읽고(공백을 제거하거나 백슬래시 제어 시퀀스를 해석하지 않고) file이를 표준 출력으로 인쇄합니다.

언제불완전한read행 읽기는 실패하지만 $line여전히 데이터를 포함합니다. 추가 -n테스트에서는 이를 감지하여 루프 본문이 불완전한 행을 출력하도록 허용합니다. 후속 반복에서는 빈 문자열로 read다시 실패하여 루프가 종료됩니다.$line


셸에 NUL 문자가 포함되어 있지 않고 셸에서 유효한 문자의 일부를 zsh형성하지 않는 바이트 시퀀스가 ​​포함되어 있지 않다고 가정하면 yash누락에도 불구하고 입력이 유효한 텍스트이면 둘 중 어느 것도 발생하지 않습니다. 마지막 줄 문자의 줄 분리로 인해 잘못된 텍스트가 되었습니다.

답변2

while 읽기 루프에 대한 입력은 다음과 같이 완료되어야 합니다:

cat /tmp/file | { cat ; echo ; } | while read -r line; do echo $line;  done

그러면 마지막 행을 포함하여 모든 행이 처리됩니다.

출처: 내 오픈 소스 프로젝트https://sourceforge.net/projects/command-output-to-html-table/

답변3

다음과 같은입력 텍스트의 마지막 줄에 불완전한 줄이 있습니다. 마지막 줄은 개행 문자로 끝나지 않습니다.루프를 동일하게 유지하고 변수 행에 반환이 있는지 확인하세요.

while read -r i
do
#
line="$(echo "$i"| sed 's/$/@/'| tr '\n' '@'|sed 's/@@/@/' |tr '@' '\n')"
#
echo $line
#
done < /tmp/file

@원하는 것으로 변경할 수 있습니다 .

관련 정보