答案 0 :(得分:231)
其中一个简单的方法是不将输出存储在变量中,而是使用while / read循环直接迭代它。
类似的东西:
grep xyz abc.txt | while read -r line ; do
echo "Processing $line"
# your code goes here
done
这个方案有不同的变化,具体取决于你所追求的目标。
如果您需要更改循环内的变量(并在其外部显示该变更),您可以使用fedorqui's answer中所述的流程替换:
while read -r line ; do
echo "Processing $line"
# your code goes here
done < <(grep xyz abc.txt)
答案 1 :(得分:17)
您可以执行以下while read
循环,该循环将使用所谓的进程替换由grep
命令的结果提供:
while IFS= read -r result
do
#whatever with value $result
done < <(grep "xyz" abc.txt)
这样,您不必将结果存储在变量中,而是直接将其输出“注入”到循环中。
根据BashFAQ / 001中的建议注意IFS=
和read -r
的使用情况:How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?:
读取的-r选项可防止反斜杠解释(通常使用 作为反斜杠换行符对,继续多行或者 逃避分隔符)。没有这个选项,任何未转义的反斜杠 在输入中将被丢弃。你应该几乎总是使用-r 阅读选项。
在上面的场景中,IFS =阻止修剪前导和尾随 空白。如果您想要这种效果,请将其删除。
关于流程替换,在bash hackers page:
中对此进行了解释进程替换是一种重定向形式,其中输入或 进程的输出(某些命令序列)显示为临时的 文件。
答案 2 :(得分:8)
我建议在这里使用awk而不是grep +其他东西。
awk '$0~/xyz/{ //your code goes here}' abc.txt
答案 3 :(得分:1)
不使用--line-buffered grep选项进行任何迭代:
your_command | grep --line-buffered "your search"
使用Symfony PHP Framework路由器调试命令输出的现实生活示例,以grep所有与“ api”相关的路由:
php bin/console d:r | grep --line-buffered "api"
答案 4 :(得分:1)
对于那些寻找单线的人:
grep xyz abc.txt | while read -r line; do echo "Processing $line"; done
答案 5 :(得分:0)
通常,处理顺序无关紧要。 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
答案 6 :(得分:0)
使用while / read循环遍历grep结果。 喜欢:
grep pattern filename.txt | while read -r line ; do
echo "Matched Line: $line"
# your code goes here
done