2012-05-15 1 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' 

? S는 대신 최장의 짧은 시퀀스를 일치 즉, 이전의 일치 비 탐욕 만든다. 검색 용어는 괄호의 외부에서 발생하는 것이 가능하다면,이 잘 작동하지 않습니다 그리고 당신은 더 명시 적으로 얻을해야합니다 :

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

'cat'을 쓸모 없게 사용합니다. – Kaz

+1

@Kaz : bash 리다이렉션 연산자를 사용하는 것보다'cat'을 사용하는 샘플에서 조금 더 명확합니다. –

+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 
관련 문제