awk: replace previous newline on match

  • Follow


Is there an easy way to replace the *previous* newline when a line 
contains a regexp match?  I suspect awk is the right tool for this, but 
I'm not very familiar with awk. It appears to be possible, but very 
clumsy, to do this with sed. I know how to do it with an ed script, but 
I would like to pipeline.
0
Reply aioe 4/27/2010 2:51:08 PM

aioe wrote:

> Is there an easy way to replace the *previous* newline when a line
> contains a regexp match?  I suspect awk is the right tool for this, but
> I'm not very familiar with awk. It appears to be possible, but very
> clumsy, to do this with sed. I know how to do it with an ed script, but
> I would like to pipeline.

Assuming your text does not appear on the very first line, with awk you can 
try this:

awk '/pattern/{p="new text"}{print p}{p=$0}END{print p}' file

With sed it's not so difficult (GNU sed syntax):

sed -n '/pattern/{x;s/.*/new text/;x;};x;p;x;h;$p' file

I can't test with ed now but I expect it to be quite simple too.

0
Reply pk 4/27/2010 2:59:08 PM


aioe schrieb:
> Is there an easy way to replace the *previous* newline when a line 
> contains a regexp match? 

You may use printf for output and prepend '\n' to subsequent lines
in case doesn't match.

   NR>1 && !/regexp/ { print "" }
   { printf "%s", $0 }
   END { print "" }


Janis

> I suspect awk is the right tool for this, but 
> I'm not very familiar with awk. It appears to be possible, but very 
> clumsy, to do this with sed. I know how to do it with an ed script, but 
> I would like to pipeline.
0
Reply Janis 4/27/2010 3:07:28 PM

On 4/27/2010 8:59 AM, pk wrote:
> aioe wrote:
>
>> Is there an easy way to replace the *previous* newline when a line
>> contains a regexp match?  I suspect awk is the right tool for this, but
>> I'm not very familiar with awk. It appears to be possible, but very
>> clumsy, to do this with sed. I know how to do it with an ed script, but
>> I would like to pipeline.
>
> Assuming your text does not appear on the very first line, with awk you can
> try this:
>
> awk '/pattern/{p="new text"}{print p}{p=$0}END{print p}' file
>
> With sed it's not so difficult (GNU sed syntax):
>
> sed -n '/pattern/{x;s/.*/new text/;x;};x;p;x;h;$p' file
>
> I can't test with ed now but I expect it to be quite simple too.
>
Thanks.  I didn't make myself clear: I want to replace only the newline 
(with space, comma, tab or something) and not the whole previous line. 
For example, I would like to join the first two lines by replacing the 
newline that precedes [ with a space, but make no other changes, in the 
following example:


  TCP    dell03:4407            mx02.eternal-september.org:nntp  ESTABLISHED
2596
  [thunderbird.exe]

  TCP    dell03:netbios-ssn     192.168.2.102:51042    TIME_WAIT       0
  TCP    dell03:netbios-ssn     192.168.2.102:51041    TIME_WAIT       0

0
Reply aioe 4/27/2010 3:38:30 PM

On 4/27/2010 9:07 AM, Janis Papanagnou wrote:
>    NR>1 && !/regexp/ { print "" }
>    { printf "%s", $0 }
>    END { print "" }

Thanks.  That works, though I would have to spend some time with my awk 
book to figure out why.

Suppose I wanted to replace the deleted newlines with tabs?

0
Reply aioe 4/27/2010 4:06:14 PM

In article <hr721b$3ur$1@speranza.aioe.org>,
aioe  <worKEEPSPAMOUTwor@bellsouth.net> wrote:
>On 4/27/2010 9:07 AM, Janis Papanagnou wrote:
>>    NR>1 && !/regexp/ { print "" }
>>    { printf "%s", $0 }
>>    END { print "" }
>
>Thanks.  That works, though I would have to spend some time with my awk 
>book to figure out why.
>
>Suppose I wanted to replace the deleted newlines with tabs?
>

You can always try this:

# ll stands for "last line"
NR > 1 { ORS=/regexp/?"\t":"\n";print ll }
{ ll = $0 }
END { if (ll) print ll }
# Note that if the regexp is present in the last line, then the last
# line won't be terminated with a newline.  This is per spec, but may
# not be desirable.

-- 
(This discussion group is about C, ...)

Wrong.  It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...

0
Reply gazelle 4/27/2010 4:40:08 PM

On Apr 27, 9:51=A0am, aioe <worKEEPSPAMOUT...@bellsouth.net> wrote:
> Is there an easy way to replace the *previous* newline when a line
> contains a regexp match? =A0I suspect awk is the right tool for this, but
> I'm not very familiar with awk. It appears to be possible, but very
> clumsy, to do this with sed. I know how to do it with an ed script, but
> I would like to pipeline.

awk '
{ printf "%s%s", (/regexp/ ? "" : n), $0; n=3D"\n"}
END { print "" }
'

    Ed.
0
Reply Ed 4/27/2010 5:00:09 PM

On Apr 27, 11:06=A0am, aioe <worKEEPSPAMOUT...@bellsouth.net> wrote:
> On 4/27/2010 9:07 AM, Janis Papanagnou wrote:
>
> > =A0 =A0NR>1 && !/regexp/ { print "" }
> > =A0 =A0{ printf "%s", $0 }
> > =A0 =A0END { print "" }
>
> Thanks. =A0That works, though I would have to spend some time with my awk
> book to figure out why.
>
> Suppose I wanted to replace the deleted newlines with tabs?

awk '
{ printf "%s%s", (/regexp/ ? t : n), $0; t=3D"\t"; n=3D"\n"}
END { print "" }
'

    Ed.
0
Reply Ed 4/27/2010 5:01:08 PM

aioe wrote:

> Thanks.  I didn't make myself clear: I want to replace only the newline
> (with space, comma, tab or something) and not the whole previous line.
> For example, I would like to join the first two lines by replacing the
> newline that precedes [ with a space, but make no other changes, in the
> following example:
> 
> 
>   TCP    dell03:4407            mx02.eternal-september.org:nntp 
>   ESTABLISHED
> 2596
>   [thunderbird.exe]
> 
>   TCP    dell03:netbios-ssn     192.168.2.102:51042    TIME_WAIT       0
>   TCP    dell03:netbios-ssn     192.168.2.102:51041    TIME_WAIT       0


Ok, so you want "join line1 and line2 if line2 matches a pattern". Since 
you've had awk solutions already, here is with sed (not because sed is 
better, but because this is listed in the sed FAQ):

sed ':a; $!N;s/\n\([^\n]*pattern\)/\1/;ta;P;D'

GNU sed syntax.
0
Reply pk 4/27/2010 5:02:48 PM

pk wrote:
> aioe wrote:
> 
>> Is there an easy way to replace the *previous* newline when a line
>> contains a regexp match?  I suspect awk is the right tool for this, but
>> I'm not very familiar with awk. It appears to be possible, but very
>> clumsy, to do this with sed. I know how to do it with an ed script, but
>> I would like to pipeline.
> 
> Assuming your text does not appear on the very first line, with awk you can 
> try this:
> 
> awk '/pattern/{p="new text"}{print p}{p=$0}END{print p}' file
> 
> With sed it's not so difficult (GNU sed syntax):
> 
> sed -n '/pattern/{x;s/.*/new text/;x;};x;p;x;h;$p' file
> 
> I can't test with ed now but I expect it to be quite simple too.
> 

Here is one:

echo '2,$g/pattern/s/^/ /\
-1,.j
w
q' | ed - file

0
Reply Jon 4/27/2010 10:06:13 PM

9 Replies
399 Views

(page loaded in 0.096 seconds)

Similiar Articles:













7/25/2012 2:33:50 AM


Reply: