Chciałbym, aby bash parsował / wyodrębniał pełny adres URL (i tylko adres URL) z losowego krótkiego ciągu.
Przykłady:
bob, the address is http://www.google.com
lub
https://foo.com/category/example.html is up
lub
Error 123 occurred at http://bit.ly/~1223456677878
lub
Stats are up: https://foo1234.net/report.jpg
Próbowałem użyć, cat foo_output | egrep -o "https?://[\w'-\.]*\s"
ale to nie działało.
bash
scripting
regular-expression
Mike B.
źródło
źródło
Odpowiedzi:
Próbowałeś:
zamiast?
Zauważ, że wszystko z klasą znaków jest traktowane jako dosłowne, więc powiedzenie
[\w]
nie pasuje do znaku słowa . Co więcej, nie musisz uciekać przed metaznakiem wyrażenia regularnego w klasie postaci, tzn. Powiedzenie[\.]
to nie to samo, co[.]
.źródło
[^ ]
jest zbyt szeroki, będziemy chcieli, aby wykluczyć inne półfabrykaty,(
,)
, ewentualnie comas, i wszystkie znaki, które nie są dozwolone w adresach URL.Identyfikatory URI nie są dobrze dopasowane do dopasowywania wyrażeń regularnych, gdy są osadzone w języku naturalnym. Jednak obecny stan techniki to Improved Liberal, Accurate Regex Pattern for Matching URLs Johna Grubera . Jak obecnie pisano, wersja jednowierszowa wygląda następująco:
John wydaje się również utrzymywać tutaj sedno , chociaż jego wpis na blogu znacznie lepiej tłumaczy jego testowy korpus i ograniczenia wzorca wyrażeń regularnych.
Jeśli chcesz zaimplementować wyrażenie z wiersza poleceń, możesz być ograniczony przez używany silnik wyrażeń regularnych lub przez problemy z cytowaniem powłoki. Odkryłem, że skrypt Ruby jest najlepszą opcją, ale przebieg może się różnić.
źródło
Problem z dopasowaniem adresów URL polega na tym, że w adresie URL może znajdować się prawie wszystko :
Jak widać, The (prawidłowy) URL powyżej zawiera
$
,?
,#
,&
,,
,.
i:
. Zasadniczo jedyne, co możesz mieć pewność, że adres URL nie zawiera, to puste miejsce. Mając to na uwadze, możesz wyodrębnić adresy URL za pomocą tak prostego wzorca, jak:\S
Mecze żadnych non-space znaków w Perl wyrażeń regularnych kompatybilny (PCREs), przy czym-P
aktywuje PCREs zagrep
i-o
czyni go wydrukować tylko dopasowany segment linii.źródło
Wybrałbym łańcuchy, ale trochę inaczej. Jeśli masz fragment tekstu podobny do twojego w pliku tekstowym o nazwie strings.txt, możesz wykonać następujące czynności:
Wyjaśnienie:
Ponieważ istnieje szansa, że adres URL może nie działać, możesz wykonać dodatkowe sprawdzanie błędów za pomocą interesującego adresu URL. np.
wget -p URL -O /dev/null
- wypisze całkiem inne kody błędów w przypadku, gdy adres URL nie jest dostępny, więc można skonfigurować pętlę do przetwarzania listy linków i wyświetlania ich statusu ważności.Jeśli ostatecznie wyodrębniasz linki z plików HTML, mogą wystąpić problemy
sed
w szczególnych przypadkach. Jak zasugerowano w zabawnym (postie) , który prawdopodobnie już widziałeś - najlepiej nie używać wyrażeń regularnych, ale silnik parsera HTML. Jednym z takich łatwo dostępnych parserów jest przeglądarka tekstowalynx
(dostępna w dowolnym systemie Linux). Pozwala to na natychmiastowe zrzucenie listy wszystkich linków w pliku, a następnie wyodrębnienie adresów URL za pomocą grep.Nie zadziała to jednak w przypadku większości zniekształconych plików HTML lub fragmentów tekstu z łączami.
źródło
Właśnie
egrep -o 'https?://[^ ")]+'
które będą zawierać
url()
i „http”źródło
egrep
jest przestarzałe.alternatywnie dodaj polecenie SED, aby zapisać go w pliku CSV:
źródło