在循环中获取GREP命令的输出



我有一个包含此搜索的shell脚本:

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

我想捕获每个字符串grep命令查找并将其发送我将创建的函数,我将创建名为" Parser"

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

如何完成?这是对的吗?

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

我不想将整个查找命令结果输出到函数

只有外壳才能执行功能。您需要在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")"' -- {} ;

上面的代码将从file1,然后将file2等发送到您的函数进行处理。它不会一个一个一个线发送每行,因此您需要在功能中的行上循环。如果文件中未出现您的正则表达式,它将 still 用空输入调用您的功能!

这可能不是最适合您的解决方案,因此让我们尝试在bash -c语句中添加循环,而则真正一个一个接一个地处理行:

parser() { 
    echo "Processing line: $1"
}
export -f parser
find . -type f -exec bash -c 'grep -iPho "barh(li|mar|ag)" "$@" | while IFS= read -r line; do parser "$line"; done' -- {} +

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

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

此方法效果很好,一一处理每行。您也不需要使用此方法导出您的功能。但是您必须关心一些可能会让您感到惊讶的事情。

管道中的每个命令均以其自己的子壳执行,并且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示例中,您将遇到相同的行为,并且您的变量分配也将丢失。

您需要导出您的功能。

您还需要致电bash才能执行函数。

parser() {
  echo "GOT: $1"
}
export -f parser
find Projects/ -type f -name '*rb' -exec bash -c 'parser "$0"' {} ;

我建议您使用sed,这是进行文本处理的功能更强大的工具。例如,我想在结尾为" ha"的行之后添加字符串" 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

如果您真的想替换文件,而不仅仅是打印到stdout,也可以像

一样执行此操作
# find . -type f -exec sed -i '/ha$/s/ha$/ha myparse/' {} ;

最新更新