Read

while read -r line || 是什麼意思?[-n$l我ne[−n$l一世n和[ -n $line]是什麼意思?

  • May 18, 2021

不久前,我發現了一些用於從文件中讀取輸入的程式碼,我相信來自 Stack Exchange,我能夠適應我的需求:

while read -r line || [[ -n "$line" ]]; do
   if [[ $line != "" ]]
   then
       ((x++));
       echo "$x:  $line"
   <then do something with $line>
   fi
done < "$1"

我現在正在審查我的腳本並試圖了解它在做什麼……我不明白這個語句在做什麼:

while read -r line || [[ -n "$line" ]];

我知道 -r 選項表示我們正在將原始文本讀入一行,但我|| [[ -n "$line" ]]對語句的部分感到困惑。有人可以解釋一下這是在做什麼嗎?

[[ -n "$line" ]]測試$line(剛剛讀取的變數read)是否不為空。它很有用,因為read當且僅當它在文件結尾之前看到換行符時才返回成功。如果輸入包含最後沒有換行符的行片段,則此測試將擷取它,並且循環也將處理最後的不完整行。如果沒有額外的測試,這樣一個不完整的行將被讀入$line,但被循環忽略。

我說的是“不完整的行”,因為文本文件的 POSIX 定義需要在每行末尾有一個換行符。其他工具read也可以關心,例如wc -l 計算換行符,因此忽略最後的不完整行。參見例如在文件末尾添加新行有什麼意義?以及為什麼文本文件應該以換行符結尾?就這樣。

cmd1 || cmd2結構當然與 C 中的等價物一樣。如果第一個命令返回錯誤狀態,則第二個命令執行,結果是執行的最後一個命令的退出狀態。

比較:

$ printf 'foo\nbar' | ( while read line; do echo "in loop: $line"; done;
                       echo "finally: $line" )
in loop: foo
finally: bar

$ printf 'foo\nbar' | ( while read line || [[ -n $line ]]; do 
                          echo "in loop: $line"; done; 
                       echo "finally: $line" )
in loop: foo
in loop: bar
finally: 

引用自:https://unix.stackexchange.com/questions/478720