下面將幾十行提取到一個變數中,但它們以某種方式全部放置在一行中。也就是說,他們失去了原來的換行符:
ALL_FOUND_LINES=$(find "$TEMP" -type f -name "debug.log*" | xargs -I {} grep -F "STARTING HOST " {})
有沒有辦法在像上面這樣的語句中保留換行符號?
答案1
如果你正在測試這個
echo $ALL_FOUND_LINES
那麼我對所有換行符都消失並不感到驚訝,因為 shell 會將$ALL_FOUND_LINES
空格、製表符和換行符(預設)中的值拆分為單字(然後透過檔案名稱產生(通配符)進一步擴展每個單字)。它這樣做是因為擴展沒有被引用。然後,該echo
實用程式會取得在一行上列印的單字清單。
更好的測試是
printf '%s\n' "$ALL_FOUND_LINES"
請注意變數擴展的引用。printf
over的選擇echo
,請參見為什麼 printf 比 echo 更好?。
您的命令可以改進為
find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +
xargs
在這裡,我們沒有將檔案名稱傳遞給,而是一次直接在盡可能多的檔案上find
執行。請注意,擺脫並不能解決換行問題,因為與此無關。這會加快速度,因為它涉及更少的.grep
debug.log*
xargs
xargs
grep
也可以看看了解“find”的 -exec 選項。
如果您需要對找到的每一行執行某些操作,那麼您可以像這樣循環它們:
find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} + |
while IFS= read -r line; do
# use "$line" here (with quotes)
done
(或將 while 迴圈替換為您需要執行的任何其他處理步驟)。因此,永遠不需要將所有資料作為換行符號分隔的字串儲存在變數中。
也可以看看理解“IFS=讀取-r行”
答案2
男人xargs
-L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x. -l[max-lines], --max-lines[=max-lines] Synonym for the -L option. Unlike -L, the max-lines argument is optional. If max-lines is not specified, it defaults to one. The -l option is deprecated since the POSIX standard specifies -L instead.