簡體   English   中英

如何確保bash中的換行符一致

[英]How to ensure consistent newline treatment in bash

我有一個簡單的腳本,該腳本使用curl獲取一些純文本文件,並將其分配給變量; 稍后它回顯並抓取它一些行,將它們放入一個臨時文件中(我實際上想將它們放入一個數組中); 然后遍歷它們並執行某些操作。 我在Mac OS X的一台計算機上運行它,並且大多數情況下都可以運行。 但是,隨機發生以下任一情況:

  • curl輸出被視為單行,因此在echo / grep階段,東西中斷了;
  • 整個tmp文件在執行回顯和for循環時都被視為單行(我似乎已使用“讀取行”緩解了此問題),因此再次中斷。

有什么方法可以確保一勞永逸地對待換行符? 我什至不在乎只要保持相同的時間,我也可以根據需要從單行curl輸出中提取結果。

更新:從另一個地方。 登錄計算機,做了一些工作,發現腳本不起作用。 跑一些命令(結果,節略的內容,如下)進行測試,注銷,重新登錄,行為更改(恢復到預期的狀態)。 請注意for循環輸出之間的區別...對於我的curl輸出來說,在完全相同的命令(據我所知)完全相同的env對待換行符方面,也會發生同樣的情況。 我想做的是在每個腳本的開頭運行一些命令,以使其100%確保行為永遠不會改變。

[root@ip-xxx-xxx-xxx-xxx ~]# cat example.txt 
ip-xxx-xxx-xxx-xxx.ec2.internal
ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# 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
[root@ip-xxx-xxx-xxx-xxx ~]# 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
[root@ip-xxx-xxx-xxx-xxx ~]# logout
Connection to ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com closed.
reznor-mbp:trunk2 sergey$ ssh -i ... "root@..."
Last login: ...
[root@ip-xxx-xxx-xxx-xxx ~]# 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

第一:不要讀取for的行; 使用while read循環讀取它們:

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

for f in $(cat example.txt)的問題在於,cat操作的輸出在進入循環之前經過字符串拆分和glob擴展,從而使行為取決於許多變量( IFS Shell設置的內容) ,當前目錄中的文件(如果存在可能的glob擴展名),影響shell解釋方式的各種shell選項等)。 while read方式將始終如一。

其次-總是出於相同的原因引用擴展名: "$line"避免字符串拆分和glob擴展(再次使上述設置和變量無意義),而裸$line會出現這種情況。

最后,上面的示例使用默認的REPLY變量,因為在這些條件下讀取時Shell不會修剪空白字符(即$IFS找到的字符)。 這通常是不必要的(通過顯式清除IFS可以達到相同的效果,就像在while IFS= read -r line; do ... ),但是由於目標是可復制的,所以我們做對了。 :)

遵循這些實踐,您將看到所有兼容POSIX sh的外殼之間的行為一致。 (唯一不符合POSIX sh的主要shell(默認情況下會在認為標准行為不合理的地方破壞兼容性)是zsh)。

你提到echo 你寫嗎

echo $multiLineVar

要么

echo "$multiLineVar"

在第一種情況下,外殼程序會將嵌入的換行符視為分隔單詞的空格,因此echo永遠不會看到它們。

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM