2017-04-18 15 views
1

我有一段時間的IFS讀取循環來檢查行中的不同匹配。如何檢查匹配的EMPTY行是否是IFS中文件的最後一行讀取

我檢查和空/空行是這樣的:

while IFS= read -r line; do 
[[ -z $line ]] && printf some stuff 

我也想檢查是否匹配的空/空也是文件的最後一行。我要上很多的文件運行此腳本,他們都:

末端有一個空行

- 他們都是一個不同長度的所以我不能假設任何事情

- 他們有其他空行,但不一定在最後(這就是爲什麼我必須區分) 在此先感謝。

+1

判斷該行是否是最後一行的唯一方法是嘗試讀取* another *行並查看它是否成功。 – chepner

+0

@chepner該死的,我有一種感覺,除了實現像這樣的東西之外它是不可能的:(。 – curiosityIsBliss

+0

可能更容易使用像awk這樣的文本解析器 – 123

回答

1

正如chepner所指出的,在外殼線讀循環只有這樣,才能知道一個給定的行是否是最後一個是嘗試讀取下一個一個

您可以模擬用下面的代碼,它允許檢測期望的條件,同時仍然在處理線均勻地「偷看」的下一行
該解決方案可能不適合每個人,因爲邏輯非常平庸,因此需要相當多的額外非顯而易見的代碼,並且處理速度也會變慢。

請注意,該代碼假定最後一行的尾部爲\n(正如所有格式正確的多行文本輸入應具有的那樣)。

#!/usr/bin/env bash 

eof=0 peekedChar= hadEmptyLine=0 lastLine=0 
while IFS= read -r line || { eof=1; ((hadEmptyLine)); }; do 

    # Construct the 1-2 element array of lines to process in this iteration: 
    # - an empty line detected in the previous iteration by peeking, if applicable 
    ((hadEmptyLine)) && aLines=('') || aLines=() 
    # - the line read in this iteration, with the peeked char. prepended 
    if ((eof)); then 
    # No further line could be read in this iteration; we're here only because 
    # $hadEmptyLine was set, which implies that the empty line we're processing 
    # is by definition the last one. 
    lastLine=1 hadEmptyLine=0 
    else 
    # Add the just-read line, with the peeked char. prepended. 
    aLines+=("${peekedChar}${line}") 

    # "Peek" at the next line by reading 1 character, which 
    # we'll have to prepend to the *next* iteration's line, if applicable. 
    # Being unable to read tells us that this is the last line. 
    IFS= read -n 1 peekedChar || lastLine=1 
    # If the next line happens to be empty, our "peeking" has fully consumed it, 
    # so we must tell the next iteration to insert processing of this empty line. 
    hadEmptyLine=$((! lastLine && ${#peekedChar} == 0)) 
    fi 

    # Process the 1-2 lines. 
    ndx=0 maxNdx=$((${#aLines[@]} - 1)) 
    for line in "${aLines[@]}"; do 
    if [[ -z $line ]]; then # an empty line 
     # Determine if this empty line is the last one overall. 
     thisEmptyLineIsLastLine=$((lastLine && ndx == maxNdx)) 
     echo "empty line; last? $thisEmptyLineIsLastLine" 
    else 
     echo "nonempty line: [$line]" 
    fi 
    ((++ndx)) 
    done 

done < file 
相關問題