下面将几十行提取到一个变量中,但它们以某种方式全部放置在一行中。也就是说,他们失去了原来的换行符:
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.