我有一个包含此搜索的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命令结果输出到函数
答案 0 :(得分:1)
只有shell才能执行某个功能。您需要在bash -c
中使用find
才能执行它。这也是您需要导出函数的原因,以便新进程可以看到它。
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等发送到你要处理的函数。 不会逐个发送每一行,因此您需要遍历函数中的行。如果文件中没有出现你的正则表达式,它将仍然用空输入调用你的函数!
这对您来说可能不是最佳解决方案,所以让我们尝试在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
此方法运行正常,将逐个处理每一行。您还不需要使用此方法导出您的函数。但是你必须要关心一些可能让你感到惊讶的事情。
管道中的每个命令都在它自己的子shell中执行,而parser
函数或while
中的任何变量赋值一般都会在从子shell返回后丢失。如果您正在编写脚本,简单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 :(得分:0)
您需要导出您的功能。
您还需要调用bash来执行该功能。
parser() {
echo "GOT: $1"
}
export -f parser
find Projects/ -type f -name '*rb' -exec bash -c 'parser "$0"' {} \;
答案 2 :(得分:0)
# 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/' {} \;