2013-03-21 31 views
2

我有一個簡單的腳本,它使用curl獲取一些純文本文件,並將其賦值給變量;後來它迴應它,併爲它的一些線,把它們放入一個臨時文件(我真的想把它們放入一個數組);然後遍歷它們並做一些事情。 我在Mac OS X上的一臺機器上運行它,它主要工作。 然而,在隨機的,或者會出現以下情況:如何確保在bash中一致的換行處理

  • 捲曲輸出被處理爲一個單一的行,所以在回波/ grep的階段,事斷裂;
  • 整個tmp文件在做echo和for循環時被當作單行處理(我似乎已經使用「read line」緩解了這個問題),所以它再次中斷。

是否有任何方法可以確保換行符一致,一勞永逸?我甚至不在乎如何,只要它總是相同的,我也可以根據需要從單線捲曲輸出中找出結果。

更新:從不同的地方。登錄到機器上,做了一些東西,發現腳本不起作用。運行一些命令(結果,刪節,下面)來測試,註銷,重新登錄,行爲改變(回到預期的狀態)。注意for循環輸出之間的差別...對於我來說,捲髮輸出也是如此,其中完全相同的命令(對於我所知道的)完全相同的env以不同的方式處理換行符。 我想要做的就是在每個腳本的開頭運行一些命令,使其100%確定該行爲永不改變。

[[email protected] ~]# cat example.txt 
ip-xxx-xxx-xxx-xxx.ec2.internal 
ip-xxx-xxx-xxx-xxx.ec2.internal 
[[email protected] ~]# for f in `cat example.txt`; do echo "line $f"; done 
line ip-xxx-xxx-xxx-xxx.ec2.internal 
ip-xxx-xxx-xxx-xxx.ec2.internal 
[[email protected] ~]# while read f; do echo "line $f"; done < "example.txt" 
line ip-xxx-xxx-xxx-xxx.ec2.internal 
line ip-xxx-xxx-xxx-xxx.ec2.internal 
[[email protected] ~]# logout 
Connection to ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com closed. 
reznor-mbp:trunk2 sergey$ ssh -i ... "[email protected]" 
Last login: ... 
[[email protected] ~]# for f in `cat example.txt`; do echo "line $f"; done 
line ip-xxx-xxx-xxx-xxx.ec2.internal 
line ip-xxx-xxx-xxx-xxx.ec2.internal 
+0

這是極不可能的環境是真正的一致。如果您可以重現隨時間變化的行爲,請記錄'printf'%q \ n'「$ - 」「$ IFS」「$ BASH_VERSION」「$( 2013-04-02 02:57:49

+0

示例1,3和4的行爲與我期望使用默認環境的方式相同。如果IFS的值已經設置爲空字符串,則示例2是我所期望的。如果這是您的意圖,則示例2也是迭代遍歷文件行的不正確方式; 'f'將迭代文件的* words *,由'IFS'的值定義。 – chepner 2013-04-02 12:20:20

回答

0

您提到echo。你寫

echo $multiLineVar 

echo "$multiLineVar" 

在第一種情況下,外殼將治療嵌入式換行符分開的話,等echo永遠看不到它們的空白。

+0

問題不在於它如何對待它們,問題在於相同的命令以不同的方式在不同的時間對待它們,因爲理由超出了我的理解 – Sergey 2013-04-02 01:39:11

4

第一:不要讀for;用while read循環閱讀:

while read -r; do 
    echo "line $REPLY" 
done <example.txt 

for f in $(cat example.txt)的問題是,貓操作的輸出通過串分裂和水珠擴張進入循環之前,決策行爲取決於許多變量(內容IFS shell設置,當前目錄中的文件[如果存在可能的glob擴展名],影響globs解釋的各種shell選項等)。 while read方法將表現一致。

第二 - 總是引用擴展出於同樣的原因:"$line"避免了字符串拆分和glob擴展(再次,使上述設置和變量無意義),而裸露的$line發生。

最後,上面的示例使用默認REPLY變量,因爲在這些條件下,shell不修剪空白字符(即$IFS中發現的字符)。這通常是不必要的(通過明確清除IFS也可以達到同樣的效果,如while IFS= read -r line; do ...),但由於目標是可重複的,因此我們做得很對。:)

遵循這些做法,您將看到符合POSIX sh的所有shell之間的一致行爲。 (唯一不符合POSIX標準的主要外殼在它認爲標準規定的行爲不合理的地方默認兼容 - 是zsh)。

+0

+1優秀的答案 – 2014-06-26 13:03:56

0

簡單的方法是使用while循環,如下

filename=/path/to/file/file.txt 
while read variablename 

do echo "$variablename" done < "filename" 它所做的是它讀取整條生產線,直到\ n