Reputation: 333
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
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
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
Reputation: 24802
Using sed
:
sed '/^from/{n;s/^/to /;b};/^to/{n;s/^/from /}'
You can try it here.
Upvotes: 3
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