sed alinha todas as linhas com a última linha em um arquivo Bash script

0

Eu tenho arquivos com linhas abaixo

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

Tentando obter a saída para um arquivo como abaixo usando sed ou qualquer outro comando

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
    
por Teja554 09.02.2016 / 07:07

1 resposta

0

Experimente este script sed: É muito hack e depende de duas coisas: o texto não contém o símbolo '|' e apenas a última linha começa com 'http:'.

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

Como funciona?

Suponha que tenhamos esta entrada:

aaa
bbb
http://zzz

Primeiro, o script combina todas as linhas do arquivo no buffer interno:

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

É um padrão muito comum em meus scripts, quando o sed não consegue processar texto por linha e a entrada não é muito grande. A partir do script de primeira linha não interrompe e apenas leia a próxima linha ('N') no buffer até o fim.

Quando chegar a última linha ('$'), pode processar mais. E quando terminou pára ('b fim'). Não se pode usar o rótulo diferente para chegar ao fim, apenas 'b' trabalho também, mas eu prefiro clareza.

Então, agora no buffer interno está este texto:

aaa\nbbb\nhttp://zzz

Em seguida, ele separa as linhas com o símbolo '|' em vez de '\ n':

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

|aaa|bbb|http://zzz

Em seguida, ele tenta encontrar esse padrão

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

e mude para isso

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

Devido à natureza gananciosa do regex usado, a substituição acontece do final para início da string, em cada passo, eliminando um símbolo '|':

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

O laço foi organizado com a ajuda do comando 't next'. Salta para rotular 'próximo' se a última substituição foi bem sucedida.

Em seguida, remove a proteção desnecessária '|' no início da linha:

s/^|//

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

E última linha:

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

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

Então, quando finalmente o buffer de impressão, você vai ter isso:

http://zzz/aaa
http://zzz/bbb
    
por 09.02.2016 / 07:33