Arteezy
Arteezy

Reputation: 333

If there's match append text to the beginning of the next line

I have a file like this

from a
b
to c
d
from e
f
from g
h
to i
j

If there's match for from, add to to the beginning of the next line. If there's a match for to, add from to the beginning of the next line. The output should be like this

from a
to b
to c
from d
from e
to f
from g
to h
to i
from j

Can this be done using any unix commands?

I have tried paste command to merge every 2 lines and then using sed. Something like this. But it's definitely wrong. Also, I don't know how to split it back again.

paste -d - - <file> | sed "s/\(^from.*\)/\1 to/" | sed "s/\(^to.*\)/\1 from/"

I think there should be an easier solution to this compared to what I'm doing.

Upvotes: 2

Views: 147

Answers (4)

Corentin Limier
Corentin Limier

Reputation: 5006

Something like this should work :

awk '
    #Before reading the file I build a dictionary that links "from" keywoard to "to" value and inversally
    BEGIN{kw["from"]="to"; kw["to"]="from"}
    #If the first word of the line is a key of my dictionary (to or from), I save the first word in k variable and print the line
    $1 in kw{k=$1;print;next} 
    #Else I add the "opposite" of k at the beginning of the line
    {print kw[k], $0} 
' <input>

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133428

Could you please try following.

awk '
{
  val=prev=="from" && $0 !~ /to/?"to "$0:prev=="to" && $0 !~/from/?"from "$0:$0
  prev=$1
  $0=val
}
1
'  Input_file

Upvotes: 2

Aaron
Aaron

Reputation: 24802

Using sed :

sed '/^from/{n;s/^/to /;b};/^to/{n;s/^/from /}'

You can try it here.

Upvotes: 3

Ed Morton
Ed Morton

Reputation: 203169

$ awk '{if ($1 ~ /^(from|to)$/) dir=$1; else $0=(dir=="from" ? "to" : "from") OFS $0} 1' file
from a
to b
to c
from d
from e
to f
from g
to h
to i
from j

Upvotes: 2

Related Questions