2017-12-03 147 views
0

我有一个shell脚本,其中包括该搜索:得到一个grep命令的输出循环

find . -type f -exec grep -iPho "barh(li|mar|ag)" {} \; 

我想捕捉每个字符串grep命令查找并发送一个我将创建一个名为“功能解析器“

parser(){ 
# do stuff with each single grep result found 
} 

该怎么办? 是这样对吗?

find . -type f -exec grep -iPho "barh(li|mar|ag)" {parser $1} \; 

我不想输出整个find命令结果的功能

回答

1

只有shell可以执行一个函数。您需要在您的find中使用bash -c才能执行它。这也是你需要导出你的函数的原因,这样新的进程才能看到它。

parser() { 
    while IFS= read -r line; do 
     echo "Processing line: $line" 
    done <<< "$1" 
} 

export -f parser 
find . -type f -exec bash -c 'parser "$(grep -iPho "barh(li|mar|ag)" "$1")"' -- {} \; 

上面的代码将发送所有出现从文件1,那么文件2等你的函数来处理。它不会由一个发送的每行一个,因此,你需要循环在你的函数中的行。如果没有你的正则表达式的发生在一个文件中,它将仍然调用函数与空输入!

这也许不是最适合你的解决方案,以便让我们尝试添加循环的bash -c声明和真的过程里面的线路逐一:

parser() { 
    echo "Processing line: $1" 
} 

export -f parser 
find . -type f -exec bash -c 'grep -iPho "barh(li|mar|ag)" "[email protected]" | while IFS= read -r line; do parser "$line"; done' -- {} + 

编辑:非常不错使用简单的解决方案bash -c @gniourf_gniourf建议:

parser() { 
    echo "Processing line: $1" 
} 

find . -type f -exec grep -iPho "barh(li|mar|ag)" {} + | while IFS= read -r line; do parser "$line"; done 

这种方式工作得很好,它过程中每行一个接一个。您也需要你的函数本办法出口。但是你必须关心一些可能让你感到惊讶的事情。

管道中的每个命令都在其自己的子shell中执行,并且在您从该子shell返回后,您的parser函数或while中的任何变量赋值都将丢失。如果您正在编写脚本,则简单的shopt -s lastpipe就足够了,并在当前shell环境中运行最后一个管道命令。或者你可以使用进程替换:

parser() { 
    echo "Processing line: $1" 
} 

while IFS= read -r line; do 
    parser "$line"; 
done < <(find . -type f -exec grep -iPho "barh(li|mar|ag)" {} +) 

注意的是,在以前bash -c的例子,你会遇到相同的行为和你的变量赋值将丢失以及。

+1

Re。 'while read'循环:如果这是OP需要的,那么'find ... -exec grep ... {} + |而读线;做解析器“$ line”;完成“是一个很好的建议。 –

+0

@gniourf_gniourf感谢您的建议!如果你不介意,我将它添加到答案中。 – PesaThe

+0

这工作对我来说: '发现。 -type f -exec grep -iPho“barh(li | mar | ag)”{} \; |而IFS =读取-r行;做解析器“$ line”;完成' ... 注意'\;'而不是'+'... 标记为答案。谢谢。 –

0

您需要导出功能。

您还需要调用bash的执行功能。

parser() { 
    echo "GOT: $1" 
} 
export -f parser 

find Projects/ -type f -name '*rb' -exec bash -c 'parser "$0"' {} \; 
+0

请注意,我说的是“grep”命令,而不仅仅是“find”。我试过这个: 'find。 -type'f -exec grep -iPho“barh(li | mar | ag)”-exec bash -c'parser“$ 0”'{} \;' 它给了我一个错误 –

+0

当然可以。但是缺少的2位是'bash -c'和'export' ;-) –

0

我建议你使用SED,这是做文字处理功能更强大的工具。 例如我想,最终的行之后添加字符串“myparse”“哈哈”,我可以做到这一点像

# echo "haha" > text1 
# echo "hehe" > text2 
# echo "heha" > text3 
# find . -type f -exec sed '/ha$/s/ha$/ha myparse/' {} \; 
haha myparse 
heha myparse 
hehe 

,如果你真的想替换的文件,而不是打印到标准输出,你可以这样做就像

# find . -type f -exec sed -i '/ha$/s/ha$/ha myparse/' {} \;