Extrai o URL do texto com vários URLs usando sed

4

Eu tenho uma string com um texto e vários URLs. Como posso extrair um URL específico (de um domínio específico) com sed? Por exemplo, eu tenho isso:

Text foo bar Text foo bar <br /><br /> http://www.this.file <br />http://another.file <br />http://mine.com/this.html <br />http://myURL.net/files/IWANTthis <br />http://www.google.com/thisnot

e sed devem retornar isto:   http://myURL.net/files/IWANTthis

    
por tzippy 10.12.2013 / 16:08

4 respostas

6

Pode haver algum problema com sed em casos especiais. Como foi sugerido em muitos lugares (por exemplo) - não usar regexps, mas um mecanismo de análise de html. Um analisador facilmente disponível está contido no texto somente navegador lynx (disponível em qualquer linux). Então você apenas extrai as urls que você quer com grep.

lynx -dump -listonly myhtmlfile.html | grep IWANTthis | sort -u

No entanto, isso não funcionará em arquivos html desconfigurados (não podem ser analisados adequadamente) ou em trechos de texto com links. Outra maneira simples é encadear. Se você tem um trecho de texto como o seu em um arquivo de texto chamado st3.txt, você pode fazer o seguinte:

grep http ./st3.txt | sed 's/http/\nhttp/g' | grep ^http | sed 's/\(^http[^ <]*\)\(.*\)//g' | grep IWANTthis | sort -u

Explicação:

grep http ./st3.txt      => will catch lines with http from text file
sed 's/http/\nhttp/g'    => will insert newline before each http
grep ^http               => will take only lines starting with http
sed 's/\(^http[^ <]*\)\(.*\)//g'   
                         => will preserve string from ^http until first space or <
grep IWANTthis           => will take only urls containing your text of interest
sort -u                  => will sort and remove duplicates from your list
    
por 10.12.2013 / 19:44
0

Você pode usar grep com uma expressão regular (regex) estendida para isso:

grep -Eo '([-+.[:alnum:]]+://)?([-[:alnum:]]+.)*myURL.net(:[[:digit:]]+)?(/[[:graph:]]*)?' <<< '<input_string>'

Explicação de cada parte do comando e da regex:

  • grep -Eo : chamamos grep com duas opções.
    • -E : Ativar POSIX estendido regexes.
    • -o : imprime somente as partes correspondentes de cada linha (sem essa opção, grep é padronizado para imprimir linhas inteiras que contenham partes correspondentes).
  • '([-+.[:alnum:]]+://)?([-[:alnum:]]+.)*myURL.net(:[[:digit:]]+)?(/[[:graph:]]*)?' : Esse regex é provavelmente um pouco mais sofisticado do que o necessário, portanto, você deve simplificar ou remover partes desnecessariamente complexas para seus propósitos. (A complexidade é o resultado de uma tentativa de fornecer uma solução geral.)
    • ([-+.[:alnum:]]+://)? : corresponde ao esquema do URL. O ? no final especifica que isso corresponde uma vez ou não a todos (para que myURL.net seja correspondido mesmo se nenhum esquema for prefixado). Incluímos os caracteres ligeiramente incomuns -+. porque RFC 3986 especifica que "os nomes dos chee consistem em uma sequência de caracteres começando com uma letra e seguida por qualquer combinação de letras, dígitos, mais ('+'), ponto final ('.') ou hífen ('-') "(ênfase minha ). Se você tiver certeza de que http:// sempre aparecerá na frente de myURL.net , poderá substituir essa parte da regex pelo simples http:// .
    • ([-[:alnum:]]+.)* : corresponde a subdomínios . O * no final especifica que isso corresponde a zero ou mais vezes (para que subdomínios como a.b. in a.b.myURL.net sejam correspondidos). Incluímos o hífen ( - ) porque RFC 1035 especifica que "[rótulos de subdomínio] devem comece com uma letra, termine com uma letra ou um dígito e tenha como caracteres internos apenas letras, dígitos e hífen "(ênfase minha). Se você tiver certeza de que não precisa corresponder a subdomínios, poderá remover essa parte da regex.
    • myURL.net : esta é uma correspondência direta para a string literal myURL.net .
    • (:[[:digit:]]+)? : corresponde a qualquer designação de porta se estiver incluída no URL.
    • (/[[:graph:]]*)? : corresponde ao resto do URL. [:graph:] corresponde a qualquer caractere visível.
  • <<< '<input_string>' : Alimentamos grep (que aceita um arquivo) nossa string de entrada usando uma string aqui . ( echo '<input_string>' | é a alternativa comum.)

Exemplo:

$ grep -Eo '([-+.[:alnum:]]+://)?([-[:alnum:]]+.)*myURL.net(:[[:digit:]]+)?(/[[:graph:]]*)?' <<< 'Text foo bar Text foo bar <br /><br /> http://www.this.file <br />http://another.file <br />http://mine.com/this.html <br />http://myURL.net/files/IWANTthis <br />http://www.google.com/thisnot'
http://myURL.net/files/IWANTthis

Mais uma vez, o regex que eu dei acima é provavelmente muito complicado para o que você precisa fazer. Você deve modificá-lo para atender às suas finalidades. Algo tão simples como o seguinte poderia funcionar:

grep -Eo 'http://myURL.net(/[[:graph:]]*)?' <<< '<input_string>'
    
por 16.12.2013 / 11:08
0

Você pode usar: sed 's/<br\ *\/>/\n/g' html_file | grep myURL.net

Saída: http://myURL.net/files/IWANTthis

Basicamente, estou substituindo todo o <br /> por um caractere de nova linha e pegando a linha relevante com grep.

Isso não leva em conta todas as variações possíveis (html permitidas) da tag <br> , mas lida com as do seu exemplo.

    
por 17.12.2013 / 10:52
0

Você pode analisar o arquivo de todos os URLs com sed e, em seguida, grep para sua correspondência.

sed "s/http/\nhttp/g" your.html | sed -n "s#\(.*\)\(http.*//[a-Z0-9./-]*[^a-Z/]\)\(.*\)##p;" | grep IWANTthis

No primeiro passo, sed substitui todo o http com uma nova linha para facilitar as coisas para sed na segunda passagem, onde sed extrai as urls. Este regex geralmente funciona para mim, mas você pode precisar ajustá-lo para atender às suas necessidades.

Nota: Você pode fazer isso de uma só vez, mas ficará complicado com a criptografia potencialmente difícil de manter os comandos sed raramente usados.

    
por 16.11.2015 / 00:32

Tags