|
|
|
|
||||||
| comp.unix.shell Using and programming the Unix shell. |
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Synopsis: I need to delete just the first line matching an expression
in a range of lines in which multiple lines match the expression. A little background: I'm working on a project in which we are converting a huge amount of Pascal code to C++. We have reasons for not using an off-the-shelf Pas-to-C translator, one of which is that much of the code we have to translate is Pascal code found in snippets in a diff file. A regular translator would not be able to make sense of such excerpts of code that are completely out of context. I've had some success using sed to create my own partial translator to with the task. Actually, I can get about three fourths of the translation done that way. Right now I'm working on a sed script to convert a Pascal case construct to a C++ switch construct. As part of this task, I automatically insert a break; statement just before every case in the construct and one break statement just before the default statement. That would be great, except that I end up with a break statement before the very first case in the switch, and I need to remove that one break statement, but leave the other break statements in the switch. Example: switch ( blah ) { break; <-- THIS break; HAS TO GO! case 1 : foobar(); break; case 2 : foobar2(); break; default : whatever(); } So far I have this in the sed script for the purpose of deleting the first break: /^[ ]*switch/,/^[ ]*break;/ { s/^[ ]*break;\n// } By the way, the break; really is followed by a newline as the result of replacing a case statement with something like "break;\ncase". Evidently, the address range matches from switch through some break statement other than the first one. How can I delete just the first break statement after the switch? Thank you. Dave |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Dave S. wrote:
> Synopsis: I need to delete just the first line matching an expression > in a range of lines in which multiple lines match the expression. > > A little background: I'm working on a project in which we are > converting a huge amount of Pascal code to C++. We have reasons for not > using an off-the-shelf Pas-to-C translator, one of which is that much > of the code we have to translate is Pascal code found in snippets in a > diff file. A regular translator would not be able to make sense of such > excerpts of code that are completely out of context. I've had some > success using sed to create my own partial translator to with the > task. Actually, I can get about three fourths of the translation done > that way. > > Right now I'm working on a sed script to convert a Pascal case > construct to a C++ switch construct. As part of this task, I > automatically insert a break; statement just before every case in the > construct and one break statement just before the default statement. > That would be great, except that I end up with a break statement before > the very first case in the switch, and I need to remove that one break > statement, but leave the other break statements in the switch. > > Example: > switch ( blah ) { > break; <-- THIS break; HAS TO GO! > case 1 : > foobar(); > break; > > case 2 : > foobar2(); > break; > > default : > whatever(); > } > > So far I have this in the sed script for the purpose of deleting the > first break: > > /^[ ]*switch/,/^[ ]*break;/ { > s/^[ ]*break;\n// > } > > By the way, the break; really is followed by a newline as the result of > replacing a case statement with something like "break;\ncase". > > Evidently, the address range matches from switch through some break > statement other than the first one. > > How can I delete just the first break statement after the switch? seems you can use: sed '/switch/{n; /break/d;}' if there are some empty lines between the 'switch' and the first 'break' statement, then you may want to add /^$/n; right after the above 'n' sed command to skip them. Xicheng |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Xicheng,
Your solution did not work when I incorporated it into my original script, but it DID work as a separate script so I'm putting it in a separate script that makes a second pass on the output. Thanks very much! Dave |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Dave S. wrote:
> Xicheng, > > Your solution did not work when I incorporated it into my original > script, but it DID work as a separate script so I'm putting it in a > separate script that makes a second pass on the output. Maybe you can try this: sed '/switch/,/case/!{/case\|default/i\ \tbreak; }' or use perl: perl -0777pe 's/(switch.*?case)|(\s*)\b(case|default)\b/$1 or "$2\tbreak;$2$3"/ges' > Dave Best regards, Xicheng |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Xicheng Jia wrote:
> Dave S. wrote: > > Xicheng, > > > > Your solution did not work when I incorporated it into my original > > script, but it DID work as a separate script so I'm putting it in a > > separate script that makes a second pass on the output. > > Maybe you can try this: > > sed '/switch/,/case/!{/case\|default/i\ > \tbreak; > }' > > or use perl: or probably: perl -pe ' s/(\s*)(case|default)/$1\tbreak;\n$1$2/ if not /switch/../case/' awk ' /switch/,/case/ { print; next } /case|default/ { print "\tbreak;" }1' Xicheng |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Dave S. wrote: > Synopsis: I need to delete just the first line matching an expression > in a range of lines in which multiple lines match the expression. > sed -e ' /switch/,/break/!b /break/d ' yourfile |
|
![]() |
| Outils de la discussion | |
|
|