PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Forums Hébergement > Forum Serveur - Sécurité et techniques > comp.unix.shell > In sed, how do you delete just the first matching line in a block of lines?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
comp.unix.shell Using and programming the Unix shell.

In sed, how do you delete just the first matching line in a block of lines?

Réponse
 
LinkBack Outils de la discussion
Vieux 18/08/2006, 17h53   #1
Dave S.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut In sed, how do you delete just the first matching line in a block of lines?

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

  Réponse avec citation
Vieux 18/08/2006, 18h56   #2
Xicheng Jia
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: In sed, how do you delete just the first matching line in a block of lines?

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

  Réponse avec citation
Vieux 18/08/2006, 21h22   #3
Dave S.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: In sed, how do you delete just the first matching line in a block of lines?

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

  Réponse avec citation
Vieux 19/08/2006, 08h03   #4
Xicheng Jia
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: In sed, how do you delete just the first matching line in a block of lines?

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

  Réponse avec citation
Vieux 19/08/2006, 08h42   #5
Xicheng Jia
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: In sed, how do you delete just the first matching line in a block of lines?

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

  Réponse avec citation
Vieux 21/08/2006, 07h26   #6
Rakesh Sharma
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: In sed, how do you delete just the first matching line in a block of lines?


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

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 17h00.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,11543 seconds with 14 queries