0

I have a files with below lines

Dev_Campaign_1873.rpm
Dev_Campaign_1987.rpm
Dev_Campaign_9876.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact

Trying to get the output to a file as below using sed or any other command

http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_1873.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_1987.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_9876.rpm

1 Answer 1

0

Try this sed script: It is very hackish and relies on two things: text doesn't contain symbol '|' and only last line begins with 'http:'.

:again
${
s/\n/|/g
# to include first part too
s/^/|/
:next
# modify last non processed part
s/\(.*\)|\([^|]\+\)|\(.*\)\(http:.*\)/\1|\4\/\2\n\3\4/
t next
# remove unneeded guard
s/^|//
# remove prefix
s/\(.*\n\)\([^\n]\+\)/\1/
b end
}
N
b again
:end

How does it work?

Suppose, that we have this input:

aaa
bbb
http://zzz

First, the script combines all lines from file into internal buffer:

:again
${
    # Here internal buffer will be processed
    b end
}
N
b again
:end

It's very common pattern in my scripts, when sed cannot process text by line and input isn't very big. Starting from first line script doesn't interupt and just read next line ('N') into buffer till the end.

When it get last line ('$') it can process further. And when it finished it stops ('b end'). One can not to use difinite label to reach end, just 'b' will work too, but I prefer clarity.

So, now in internal buffer is this text:

aaa\nbbb\nhttp://zzz

Next it separates lines with symbol '|' instead of '\n':

s/\n/|/g
# to include first part too
s/^/|/

|aaa|bbb|http://zzz

Then it tries to find this pattern

...|text|.....http://...

and change it to this

...|http://...text\n.....http://...

Due to greeding nature of used regex, the substitution happens from the end to start of string, on each step eliminating one symbol '|':

Initial state of buffer:
|aaa|bbb|http://zzz

After first step:
|aaa|http://zzz/bbb\nhttp://zzz

After second step:
|http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz

Loop was organized with the help of command 't next'. It jumps to label 'next' if last substitution was successful.

Next it removes unneeded guard '|' at the start of line:

s/^|//

http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz

And last line:

s/\(.*\n\)\([^\n]\+\)/\1/

http://zzz/aaa\nhttp://zzz/bbb

So, when it finally print buffer, you'll get this:

http://zzz/aaa
http://zzz/bbb

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .