我正在做以下,基本上工作。 該腳本嘗試在文件中插入一些行以重寫它。Bash腳本通過循環輸入循環
但它是剝離所有空行和所有行填充。 主要問題是它不處理文件的最後一行。 我不知道爲什麼。
while read line; do
<... process some things ...>
echo ${line}>> "${ACTION_PATH_IN}.work"
done < "${ACTION_PATH_IN}"
可以做些什麼來解決這個問題?
我正在做以下,基本上工作。 該腳本嘗試在文件中插入一些行以重寫它。Bash腳本通過循環輸入循環
但它是剝離所有空行和所有行填充。 主要問題是它不處理文件的最後一行。 我不知道爲什麼。
while read line; do
<... process some things ...>
echo ${line}>> "${ACTION_PATH_IN}.work"
done < "${ACTION_PATH_IN}"
可以做些什麼來解決這個問題?
while IFS= read -r line; do
## some work
printf '%s\n' "$line" >> output
done < <(printf '%s\n' "$(cat input)")
read
不剝離的前緣和後空格。read -r
防止EOL中的反斜槓創建行延續。"$line"
)以防止shell對其值進行分詞和匹配。printf '%s\n'
代替echo
,因爲它處理值等像-e
,-n
等< <(printf '%s\n' "$(cat input)")
是LF的醜陋的方式終止的input
內容時是可靠的。其他結構也是可能的,這取決於你的要求(如果你的整個while
運行在一個子shell中,管道而不是從過程替換重定向)。 不讀取最後一行的一個可能原因是該文件沒有以換行符結束。總的來說,我希望它能夠工作,但這可能是爲什麼。
在MacOS X(10.7.1),我得到這個輸出,這是您所看到的行爲:
$ /bin/echo -n Hi
Hi$ /bin/echo -n Hi > x
$ while read line; do echo $line; done < x
$
最明顯的解決方法是,以確保該文件以換行符結束。
第一件事情,用
echo "$line" >> ...
注意引號。如果你不放它們,殼本身將會移除填充。
至於最後一行,這很奇怪。它可能與文件的最後一行是否由\n
終止有關(這是一個很好的做法,幾乎所有的編輯都會爲你做這件事)。
最好,使用一個工具,如awk
而不是shell的while
循環。首先,awk
是用於解析/操作文件,因此對於處理大文件,awk
具有優勢。其次,你不必關心你是否有最後一個換行符(對於你的情況)。
因此您while read
迴路的等效:
awk '{
# process lines
# print line > "newfile.txt"
}' file
如果'IFS'已設置爲讀取,不需要最後'printf',因爲'read'實際上將讀取所有的行逐字(包括空格),因爲'cat'只是對文件內容沒有任何影響,但將它們複製到管道中。 –
@Diego:'printf'foo \ n \ n bar'| bash -c'while IFS = read -r line;做printf「<<%s>> \ n」「$ line」; done''從不處理最終的非LF終止的「bar」行。來自流程替代的重定向中的'printf'是在那裏添加一個尾隨LF(如果原始內容沒有一個;這不是關於保留空白,而是要正確處理最後一行。 –
@Diego:你是正確的,'read'將讀取最終的非LF終止行,但它也返回非零值,它退出循環(因此這樣的行絕不會被循環體處理)。 –