2

I am using the below SED command:

sed '/cell.* '"alatch {"'/,/^}/p' -n file 

Input file is as under:

cell abc { pins on T { a b c } } cell xyz { pins on T { x y z } } cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } 

Output is as under:

cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } 

Expected out is as under:

cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } 

What is needed is that only the first occurrence should be the output. Any suggestion for command?

1
  • Clarify the exact occurrence of what you want. Also, I don't think your quoting, while probably not incorrect, makes much sense and only obfuscates the sed command. How about '/cell.* alatch {/,/^}/p' as a start? Commented Feb 15, 2021 at 10:54

2 Answers 2

5

Assuming you want the first of the two identical blocks:

$ sed '/cell alatch {/,/^}/!d; /^}/q' file cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } 

The /cell alatch {/,/^}/ range is the range of lines that you want to get as output.

The sed expressions first deletes all lines not in this range, and then quits as soon as a } is found at the start of a line. The q instruction will cause sed to terminate after it outputs the current line, so the final } will get printed.

Executing the d instruction immediately skips to the next input line and branches back to the start of the editing script, so the q instruction has no way of executing unless it's in the range which does not cause d to execute.


With awk, achieving the same effect with code that should be reminiscent of the sed code above:

$ awk '/cell alatch {/,/^}/ { print; if ($0 ~ /^}/) exit }' file cell alatch { pins on T { VSS VDDPI VDDP } pins on L { IN CT CB } pins on R { OUT } inputs { CB CT IN } outputs { OUT } } 

Actually, this is closer to the sed command

sed -n '/cell alatch {/,/^}/{ p; /^}/q; }' file 

which does the same thing.

2

With awk we accumulate the desired cell data and when the depth (number of { = number of } reaches 0 we dump the cell data nd quit.

awk ' BEGIN { ORS = "" } /cell alatch \{/ {inCell=1} !inCell {next} {data = data $0 RS} /\}/ {depth--} /\{/ {depth++} !depth { print data exit } ' ./file 

Using GNU sed with the same idea of the awk code above.

sed -e ' /cell alatch {/!d /\n/!{h;s/.*/x/;x;} $d;N /}$/{x;s/x//;/x/!{x;q;};x;} /{$/{x;s/$/x/;x;} s/^/\n/;D ' file 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.