Pytanie Jak znaleźć informacje w tagu XML używając grep?


Pracuję nad skryptem powłoki Linuxa, aby znaleźć informacje w pliku xml za pomocą grep. Jestem na macu, który, mam nadzieję, nie ma większego znaczenia.

Aby znaleźć potrzebne informacje, uruchamiam:

grep -oP "<title>(.*)</title>" temp.xml

Dostaję w zamian listę meczów i obejmuje to <title> etykietka.

Jak mogę uzyskać listę zawierającą tylko informacje wewnątrz title tag, ale bez  title tag za pomocą grep?


10
2018-05-28 08:43


pochodzenie


Dlaczego zamiast tego nie używasz XPath? - toniedzwiedz
To musi być szybkie zadanie skryptowe, nie chciałbym spędzać na nim wieków. Czy możesz polecić dobre narzędzie wiersza poleceń xpath? - Filype
Wygląda na to, że mam już zainstalowany xpath5.12. Bez ręcznego wprowadzania - Filype
Każdy z nich wystarczy. Twój XPath będzie tak prosty jak to tylko możliwe "// title / text ()" - toniedzwiedz
Ture, nie wiedziałem, że xpath jest narzędziem wiersza poleceń. - Filype


Odpowiedzi:


Nie widzę powodu, dla którego chciałbyś użyć grep do tego, a można to rozwiązać za pomocą trywialnego wyrażenia XPath:

//title/text()

Istnieje wiele narzędzi wiersza poleceń dla XPath i zazwyczaj są one dostarczane razem z systemem operacyjnym.

Odpowiedzi na to pytanie w Stack Overflow wymień kilka takich narzędzi.

Problem z grep tutaj jest to ogólne narzędzie do przetwarzania tekstu i nie jest ono świadome żadnej struktury XML. Dla bardzo prostego scenariusza możesz działaj. Jeśli dokument jest złożony lub jeśli używasz go w skrypcie, który przetrwa miesiące lub lata, a nie tylko jednorazową pracę, może skończyć się przykro z powodu wyników.

XPath ułatwia odróżnienie podobnie nazwanych znaczników, które pojawiają się w różnych kontekstach w dokumencie.

<article>
    <author>
        <name>Jon Doe</name>
        <title>Chief Editor</title>
    </author>
    <title>On the Benefits of grep</title>
    <publicationDate>2018-02-12</publicationDate>
    <text>blah blah blah</text>
</article>

Wyodrębnianie tytułu artykułu reprezentowanego przez ten dokument za pomocą grep zakończyłoby się niepowodzeniem, jeśli użyłeś żadnej z zamieszczonych tutaj odpowiedzi. Możesz technicznie napisać wyrażenie regularne, aby uzyskać to, czego potrzebujesz, ale znacznie łatwiej z XPath.

/article/title/text()

Jeśli wiesz, że masz do czynienia z banalnym dokumentem i format się nie zmienia lub jeśli jest to jednorazowa praca, w której możesz szybko sprawdzić wyniki, możesz przejść do grep jak wyjaśniono przez innych.


3
2018-05-28 09:55



Przykładami poleceń obsługujących XPath są xgrep (wohlberg.net/public/software/xml/xgrep), xmlgrep (search.cpan.org/dist/XML-Twig/tools/xml_grep/xml_grep) lub sgrep (cs.helsinki.fi/u/jjaakkol/sgrep.html). - Claudix
Czego nie rozumiesz w (jasnym) pytaniu, które kończy się na: "używanie grep"? - Moonchild
Czego nie rozumiesz w odpowiedzi, dostarczając użytecznej odpowiedzi na pytanie, które odnosi się do sedna problemu, w przeciwieństwie do założeń przyjętych przez PO. Dlaczego cię to trapi? - toniedzwiedz
Zobacz też stackoverflow.com/questions/15461737/... dla katalogu narzędzi XPath dla U * x. - tripleee
Zadaj pytanie dotyczące pomarańczy, a zaakceptowana odpowiedź dotyczy bananów. Miły. Oto wskazówka: wskazówki przechodzą w komentarzach, a nie odpowiedzi. - Christian


Ponieważ już używasz grep -P, dlaczego nie używasz jego funkcji?

grep -oP '(?<=<title>).*?(?=</title>)'

W ogólnym przypadku XPath jest właściwym rozwiązaniem, ale w przypadku scenariuszy zabawek, tak, Virginia, można to zrobić.


15
2018-05-28 10:50



ale teraz grep -P jest przestarzały - Bharat
@Bharat Przestarzały ?? Czy możesz podać referencję? - tripleee
Fakt, że OSX zdecydował się usunąć użyteczną funkcjonalność, ledwo wskazuje, że funkcja jest przestarzała. Nic nie wskazuje na to, że zostanie on usunięty z GNU grep który jest łatwy do zainstalowania na OS X, jeśli jest potrzebny, i standard na większości innych platform w dzisiejszych czasach. - tripleee
mój błąd. Uzgodnione :) - Bharat
man perlre - (?<=pattern) jest asercją lookbehind i (?=pattern) jest stwierdzeniem z wyprzedzeniem. - tripleee


To nie jest najlepsze rozwiązanie, będę szukał biblioteki XML w bash, ale możesz zrobić:

grep -oP "<title>(.*)</title>" temp.xml | cut -d ">" -f 2 | cut -d "<" -f 1

3
2018-05-28 09:10



To także moje rozwiązanie. - Filype


Możesz zainstalować xgrep używając xpath zgodnie z sugestią Tomekodpowiedź

człowiek xgrep


1
2018-02-11 15:25