2017-12-03 145 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/' {} \;