P.goutham
P.goutham

Reputation: 51

Need to extract the text in first occurrence of pattern

I have one file where it consists of several lines like below:

 part1 { CORE_LK0 }  -group { LK0_GROUP } -module { 20rx }
 Ignore no3  { CORE_ft0 } -sync { n7 }

I need to extract the text in first occurrence of {}. I tried this :

grep "{.*}" file.txt

My output:

part1 { CORE_LK0 }  -group { LK0_GROUP } -module { 20rx }
Ignore no3  { CORE_ft0 } -sync { n7 }

But desired output is need to grep only the first occurrence of {}:

CORE_LK0
CORE_ft0

Can anyone help me in this.

Upvotes: 1

Views: 624

Answers (3)

dawg
dawg

Reputation: 103744

You can do this with Perl:

$ perl -lnE 'say $1 if /^[^{]*\{([^}]*)\}/' file
 CORE_LK0 
 CORE_ft0 

Regex explanation:

/^[^{]*\{([^}]*)\}/


 ^                    start of line anchor
  ^  ^                character class
   ^                  negated -- any character OTHER THAN {
      ^               * is 0 or more of that character class
       ^              \{ is a literal {
         ^    ^       (    ) capture group to define $1 
           ^ ^        0 or more characters OTHER THAN }
                 ^    literal }      

Upvotes: 0

RavinderSingh13
RavinderSingh13

Reputation: 133428

Could you please try following.

awk 'match($0,/{ [^}]*/){print substr($0,RSTART+2,RLENGTH-2)}'  Input_file

Explanation:

awk '                                     ##Starting awk program from here.
match($0,/{ [^}]*/){                      ##Using match function to match from { to till first occurence of }
  print substr($0,RSTART+2,RLENGTH-2)     ##printing sub-string of current line from RSTART+2 to til RLENGTH-2
}
'  Input_file                             ##Mentioning Input_file name here.


2nd solution: Just for fun, recommended is above solution only(written in GNU grep and tested with shown samples only).

rev Input_file | grep -oP '.*} \K.*' | rev | grep -oP '.* { \K.*'

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626709

You may use sed for this:

sed -n 's/^[^{}]*{ *\([[:alnum:]_]*\) *}.*/\1/p' file > results

Or, if there can be any chars but { and } in between the first set of curly braces,

sed -n 's/^[^{}]*{ *\([^{}]*\) *}.*/\1/p' file > results

See the online demo.

Details

  • -n - suppresses the default line output (unmatched lines won't get printed)
  • s/ - substitution command
  • ^[^{}]*{ *\([[:alnum:]_]*\) *}.* - match
    • ^ - start of string
    • [^{}]* - 0 or more chars other than { and }
    • { * - { and 0 or more spaces
    • \([[:alnum:]_]*\) - Capturing group 1: any 0 or more letters, digits or _
    • *} - 0 or more spaces and }
    • .* - the rest of the line
  • \1 - replace with the whole line with the contents of Group 1
  • p - prints the value that was in Group 1.

Upvotes: 1

Related Questions