如何在 xargs -I {} 上保留換行符

如何在 xargs -I {} 上保留換行符

下面將幾十行提取到一個變數中,但它們以某種方式全部放置在一行中。也就是說,他們失去了原來的換行符:

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"

請注意變數擴展的引用。printfover的選擇echo,請參見為什麼 printf 比 echo 更好?


您的命令可以改進為

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +

xargs在這裡,我們沒有將檔案名稱傳遞給,而是一次直接在盡可能多的檔案上find執行。請注意,擺脫並不能解決換行問題,因為與此無關。這會加快速度,因為它涉及更少的.grepdebug.log*xargsxargsgrep

也可以看看了解“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.

相關內容