如何在 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.

相关内容