Sed substitui porções de linhas que não começam com http: //

1

Estou ficando preso com o sed .. Estou tentando prefixar os links em um arquivo html com um / quando eles não começam com http. Estou ciente de que este não é possivelmente o melhor caminho a percorrer isso, mas eu estou apenas depois de um simples rápido / solução.

Até agora, eu tentei isso (note IRL eu vou usar o sinalizador -i no local, etc, isso é apenas para testes):

echo '<a href="egww">blah</a><a href="http://bloge.weg">yeah</a>' |
sed 's@href="[^http]@href="/@g'

Isso quase funciona:

<a href="/gww">blah</a><a href="http://bloge.weg">yeah</a>

Exceto que o primeiro caractere do primeiro link foi cortado, também acho que não corresponde a h, t, t ou p, em vez da string inteira http:

echo '<a href="egww">blah</a><a href="p/bloge.weg">damn</a>' |
sed 's@href="[^http]@href="/@g'

<a href="/gww">blah</a><a href="p/bloge.weg">damn</a>

Estou bastante perplexo neste ponto, infelizmente o google não ajuda muito aqui, pois a negação com sed geralmente é usada para remover linhas que contêm uma string, em vez de não corresponder a substrings em linhas .. Tentei várias expressões regulares 'normais' padrões, mas estes não parecem funcionar.

Alguma idéia?

    
por John Hunt 18.09.2015 / 11:35

1 resposta

4

[^http] não é nada, exceto http . Essa RE corresponde a um caractere, desde que não seja h nem t nem p . Portanto, href="[^http] corresponde a href="b em href="blah" , mas não href="t em href="toto" .

Aqui, você gostaria de algo como:

sed -E 's@(href=")([^h]|h([^t]|t([^t]|t([^p]|$)|$)|$)|$)@/@g'

Isso é href=" seguido por não- h (um caractere diferente de h ) ou h -não- t ou ht -não t ou htt -não- p ou htt -EOL ou ht -EOL ou h -EOL ou EOL. (EOL == "fim da linha", os 4 últimos que não podem ser encontrados na entrada, pois isso significaria que o " não é correspondido).

(assumindo que seu sed suporta a opção -E ainda não padrão).

Você também pode adicionar / , mas removê-lo depois, quando em href="/http :

sed 's@href="@&/@g;s@href="/http@href="http@g'

Ou com perl :

perl -pe 's|href="\K(?!http)|/|g'

Usando o operador RE de look-ahead negativo de perl .

    
por 18.09.2015 / 11:53