2012-05-15 17 views
0

我有很多大文本文件被已知分隔符{{}分組爲分組。如果一個塊包含一個特定的序列,比如xyq,那麼我想輸出整個塊。根據內容在Linux中輸出文本塊

我知道我可以寫一個grep讓我搜索標籤,但我怎麼能擴大我的選擇到最近的括號? 注意,{和}可以位於任何地方,即不啓動或行,空格,結束...

尋找這樣的事情:

Input: 
{i am a turtle} 
{i am a horse} 
{i am a programmer} 

grep ???programmer??? ./File 

output: {i am a programmer} 
+0

這些大括號可以嵌套嗎? '{我是{烏龜}}'? – Kaz

回答

1

你可以試着翻譯成新行別的東西第一。假設輸入沒有NUL,這是一個很好的候選人。

cat input | tr '\n' '\0' | grep -aEo '\{.*?programmer.*?\}' | tr '\0' '\n' 

在正則表達式本身,?奇妝之前的比賽非貪婪的,這意味着它們匹配最短的序列,而不是最長的。請注意,如果括號外面發生的搜索來看,它是可能的,這將無法正常工作,你需要得到更明確的:

cat input | tr '\n' '\0' | grep -aEo '\{[^{}]*programmer[^{}]*\}' | tr '\0' '\n' 
+0

無用的'貓'。 – Kaz

+1

@Kaz:使用'cat'的示例比使用bash重定向操作符更清晰一些。 –

+0

' output' – Kaz

0
sed -n '/{\|}/ !{H; b}; /{/ {h; b open}; :open {/}/ b close; n; H; b open}; :close {g; /programmer/ p}' File 

說明:

$ sed -n '#suppress printing of all input 
> /{\|}/ !{H; b} # if no curly brackets on the line, append it to hold space and finish 
> /{/ {h; b open} # if an opening { is found, copy the line to hold space and branch to label :open 
> :open 
> /}/ b close # if a } is matched, branch to label close 
> n; H; b open # else read a new line, append it to hold space and go back to :open 
> :close 
> g # put all hold space to pattern space 
> /programmer/ p # if _programmer_ matches, print the pattern space' File 
0
>cat file 
{i am a turtle} 
    jay {i am a horse} 
    {i am a programmer} 



>grep horse file | awk -F"{}" '{print substr($2,0,length($2)-1)}' 



i am a horse