У меня есть файлы с нижними строками

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

Попытка получить вывод в файл, как показано ниже, используя sed или любую другую команду

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 ответ1

0

Попробуйте этот скрипт: он очень хакерский и основан на двух вещах: текст не содержит символ '|' и только последняя строка начинается с '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

Как это работает?

Предположим, что у нас есть этот вход:

aaa
bbb
http://zzz

Во-первых, скрипт объединяет все строки из файла во внутренний буфер:

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

Это очень распространенный шаблон в моих сценариях, когда sed не может обрабатывать текст построчно, а ввод не очень велик. Начиная с первой строки, скрипт не прерывается и просто читает следующую строку ('N') в буфер до конца.

Когда он получает последнюю строку ('$'), он может обрабатываться дальше. И когда это закончено, это останавливается ('конец'). Нельзя использовать дифинитную метку для достижения цели, просто «b» тоже подойдет, но я предпочитаю ясность.

Итак, теперь во внутреннем буфере находится этот текст:

aaa\nbbb\nhttp://zzz

Далее он разделяет строки с символом '|' вместо '\n':

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

|aaa|bbb|http://zzz

Затем он пытается найти эту модель

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

и изменить это на это

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

Из-за жадности используемого регулярного выражения замена происходит от конца до начала строки, на каждом шаге удаляется один символ '|':

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

Цикл был организован с помощью команды 't next'. Он переходит к метке «следующий», если последняя замена прошла успешно.

Затем он удаляет ненужную охрану '|' в начале строки:

s/^|//

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

И последняя строка:

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

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

Итак, когда он, наконец, напечатает буфер, вы получите это:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .