web-dev-qa-db-fra.com

Texte entre deux balises

Je veux récupérer ce qui se trouve entre ces deux balises - <tr> </tr> - à partir d'un document html. Maintenant, je n'ai pas d'exigences HTML spécifiques qui justifieraient un analyseur HTML. J'ai simplement besoin de quelque chose qui correspond à <tr> et </tr> et obtient tout entre les deux et il peut y avoir plusieurs trs. J'ai essayé awk, qui fonctionne, mais pour une raison quelconque, il finit par me donner des doublons de chaque ligne extraite.

awk '
/<TR/{p=1; s=$0}
p && /<\/TR>/{print $0 FS s; s=""; p=0}
p' htmlfile> newfile

Que faire à ce propos?

24
TechJack

Si vous voulez seulement ... De tous <tr>...</tr> Faites:

grep -o '<tr>.*</tr>' HTMLFILE | sed 's/\(<tr>\|<\/tr>\)//g' > NEWFILE

Pour les multilignes:

tr "\n" "|" < HTMLFILE | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g;s/|/\n/g' > NEWFILE

Vérifiez d'abord le HTMLFILE du caractère "|" (pas habituel, mais possible) et s'il existe, changez-en un qui n'existe pas.

15
xx4h

Vous avez une exigence qui garantit un analyseur HTML: vous devez analyser HTML. Perl's HTML :: TreeBuilder , Python BeautifulSoup et d'autres sont faciles à utiliser, plus facile que d'écrire des expressions régulières complexes et fragiles.

Perl -MHTML::TreeBuilder -le '
    $html = HTML::TreeBuilder->new_from_file($ARGV[0]) or die $!;
    foreach ($html->look_down(_tag => "tr")) {
        print map {$_->as_HTML()} $_->content_list();
    }
' input.html

ou

python -c 'if True:
    import sys, BeautifulSoup
    html = BeautifulSoup.BeautifulSoup(open(sys.argv[1]).read())
    for tr in html.findAll("tr"):
        print "".join(tr.contents)
' input.html

sed et awk ne sont pas bien adaptés à cette tâche, vous devriez plutôt utiliser un analyseur html approprié. Par exemple hxselect de w3.org:

<htmlfile hxselect -s '\n' -c 'tr'
9
Thor

Si Ruby est disponible, vous pouvez procéder comme suit

Ruby -e 'puts readlines.join[/(?<=<tr>).+(?=<\/tr>)/m].gsub(/<\/?tr>/, "")' file

file est votre fichier html d'entrée. La commande exécute un Ruby one-liner. Premièrement, elle lit toutes les lignes de file et les joint à une chaîne, readlines.join. Ensuite, à partir de la chaîne il sélectionne n'importe quoi entre (mais sans inclure) <tr> et <\/tr> qui est un caractère ou plus indépendamment des nouvelles lignes, [/(?<=<tr>).+(?=<\/tr>)/m]. Ensuite, il supprime tout <tr> ou </tr> à partir de la chaîne, gsub(/<\/?tr>/, "") (cela est nécessaire pour gérer les balises tr imbriquées). Enfin, il imprime la chaîne, puts.

Vous avez dit qu'un analyseur html n'est pas garanti pour vous, mais qu'il est très facile à utiliser Nokogiri avec Ruby et rend la commande plus simple.

Ruby -rnokogiri -e 'puts Nokogiri::HTML(readlines.join).xpath("//tr").map { |e| e.content }' file

-rnokogiri Charge Nokogiri. Nokogiri::HTML(readlines.join) lit toutes les lignes de file. xpath("//tr") sélectionne chaque tr élément et map { |e| e.content } sélectionne le contenu de chaque élément, c'est-à-dire ce qui est entre <tr> et </tr>.

5
N.N.

grep

Pour récupérer le contenu de la balise tr sur plusieurs lignes, passez-le d'abord par xargs, par exemple:

curl -sL https://www.iana.org/ | xargs | egrep -o "<tr>.*?</tr>"

Pour renvoyer uniquement du HTML interne, utilisez:

curl -sL https://www.iana.org/ | xargs | grep -Po "<tr>\K(.*?)</tr>" | sed "s/..tr.//g"

Vérifiez la syntaxe pour perlre modèles étendus .

Remarque: Pour des performances plus rapides, vous pouvez envisager ripgrep qui a une syntaxe similaire.

1
kenorb

s'il s'agit simplement d'une liste rapide de <tr>s cela pourrait aider:

Perl -ne 'print if /<tr>/../</tr>/' your.html > TRs.log

à votre santé

0
eswues

pup

Exemple utilisant pup (qui utilise sélecteurs CSS ):

pup -f myfile.html tr

Pour imprimer uniquement du texte sans balises, utilisez: pup -f myfile.html tr text{}.

Voici quelques exemples avec curl:

curl -sL https://www.iana.org/ | pup tr text{}
pup -f <(curl -sL https://www.iana.org/) tr text{}

xpup

Exemple utilisant xpup pour l'analyse HTML/XML (qui prend en charge XPath):

xpup -f myfile.html "//tr"
0
kenorb