Answers:
一种简单的方法是不将输出存储在变量中,而是通过while / read循环直接对其进行迭代。
就像是:
grep xyz abc.txt | while read -r line ; do
echo "Processing $line"
# your code goes here
done
此方案有多种选择,具体取决于您要使用的内容。
如果您需要在循环内更改变量(并使更改在外部可见),则可以按照fedorqui的回答所述使用流程替换:
while read -r line ; do
echo "Processing $line"
# your code goes here
done < <(grep xyz abc.txt)
while read p || [[ -n $p ]]; do ...
从stackoverflow.com/questions/1521462/…借用)
您可以执行以下while read
循环,该循环将grep
使用所谓的进程替换由命令的结果提供:
while IFS= read -r result
do
#whatever with value $result
done < <(grep "xyz" abc.txt)
这样,您不必将结果存储在变量中,而是直接将其输出“注入”到循环中。
请注意BashFAQ / 001中的用法IFS=
并read -r
根据BashFAQ / 001中的建议进行操作:如何逐行(和/或逐字段)读取文件(数据流,变量)?:
读取的-r选项可防止反斜杠解释(通常用作反斜杠换行符,可在多行上继续或转义定界符)。如果没有此选项,则输入中任何未转义的反斜杠将被丢弃。您几乎应该始终将-r选项与read结合使用。
在上述情况下,IFS =可防止修剪前导和尾随空白。如果需要此效果,请将其删除。
关于进程替换,在bash黑客页面中进行了解释:
进程替换是一种重定向形式,其中进程的输入或输出(某些命令序列)显示为临时文件。
for
版本。试图"${$(grep xyz abc.txt)[@]}"
像在stackoverflow.com/a/14588210/1983854中那样做一个循环,但是不能。所以我只保留第一个版本。
zsh
,在这种嵌套可能起作用的地方)。
while IFS= read -r result <&3
和done 3< <(grep ...
我建议在这里使用awk而不是grep +其他方式。
awk '$0~/xyz/{ //your code goes here}' abc.txt
//your code goes here
?
使用--line-buffered grep选项无需任何迭代:
your_command | grep --line-buffered "your search"
现实生活中使用Symfony PHP Framework路由器调试命令输出,以grep所有与“ api”相关的路由:
php bin/console d:r | grep --line-buffered "api"
tail -f some.log
,就我而言),
通常,处理顺序无关紧要。GNU Parallel适用于这种情况:
grep xyz abc.txt | parallel echo do stuff to {}
如果您处理的更像是:
grep xyz abc.txt | myprogram_reading_from_stdin
并且myprogram
很慢,那么您可以运行:
grep xyz abc.txt | parallel --pipe myprogram_reading_from_stdin
grep -o
这种事情的力量。该-o
标志将仅返回匹配的文本,每行输出一个匹配项。(这并不详尽,因此echo aaa |grep 'a*'
只给您“ aaa”,并省略了三个部分匹配项“”,“ a”和“ aa”)