İki etiket arasındaki metin


23

Bu iki etiket arasındakileri bulmak isterim - <tr> </tr>- bir html belgesinden. Şimdi bir html ayrıştırıcısı için herhangi bir özel html gereksinimim yok. Ben sadece düz ihtiyaç şey maçlar olduğunu <tr>ve </tr>ve aradaki her şeyi alır ve birden olabilir trler. İşe yarayan awk'ı denedim, ancak bir nedenden dolayı, çıkarılan her satırın kopyalarını vermemle sonuçlandı.

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

Bu konuda gitmek nasıl?


IIUC senin awk komut olmalıdır: '/<tr/{p=1}; p; /<\/tr>/{p=0}'. Çalışmazsa, bazı örnek girdiler ve beklenen çıktılar gönderin.
Thor

çünkü awkçalışıyor, ama yinelenenlere sort -usahip olmak
awk'ların çıktılarını

Yanıtlar:


14

Sadece ...hepsini <tr>...</tr>yapmak istiyorsanız :

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

Multiline için:

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

Önce "|" karakterinin HTMLFILE'ini kontrol edin (normal değil ama mümkün) ve varsa, mevcut olmayanla değiştirin.


1
Bu yalnızca başlangıç ​​ve bitiş etiketleri aynı satırdaysa çalışır.
l0b0

echo "bla<tr>foo</tr>bla<tr>bar</tr>bla" | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g'verir fooblabar. blaOlmamalı?
NN

@ l0b0 doğru. çok satırlı uyumlu bir ürün için gideceğim ...
xx4h

grep -Po '<tr>.*?</tr>'@ NN'nin durumunda satır başına bir sonuç döndürürdü, ancak taşınabilir değil.
l0b0

'Specs' veya 'spec-style' ile ne kastettiğinizi bilmiyorum ama web tarayıcınızın bir html ayrıştırıcısı kullandığını ve bir html ayrıştırıcısının nasıl yazıldığına bakılmaksızın html'yi ayrıştırdığını unutmayın . Html olmayan şeyleri ayrıştırmaz, ancak o zaman tarayıcınız da olmaz, bu nedenle kimse bir ayrıştırıcının çözümleyemediği "html" yazmasını zahmete sokmaz. Başka bir deyişle: İyi bir çözümleyici kesinlikle bunu yapmak için kesinlikle en iyi bahis.
goldilocks

11

Bir HTML ayrıştırıcısını garanti eden bir gereksiniminiz var: HTML'yi ayrıştırmanız gerekir. Perl'in HTML'si: TreeBuilder , Python'un BeautifulSoup'u ve diğerlerinin kullanımı kolaydır, karmaşık ve kırılgan düzenli ifadeler yazmaktan daha kolaydır.

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

veya

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

9

sedve awkbu görev için uygun değil, uygun bir html ayrıştırıcı kullanmalısınız. Örneğin hxselect, w3.org'dan:

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

Hxselect en iyi seçenek olup olmadığını bilmiyorum; Ben kullanmadım, ancak man sayfası pek çok HTML belgesinin olmadığı "iyi biçimlendirilmiş bir XML belgesi okuyor" diyor. Muhtemelen bir denemeye değer. Html ayrıştırıcı libleri perl, python, et. ark. bir seçenek ise, çok daha iyi olacak.
goldilocks

2
@goldilocks: En iyi seçim duruma göre değişir. Tecrübelerime göre hxselectiyi biçimlendirilmiş html / xml dökümanları ile oldukça iyi iş çıkarıyor. Ayrıca perl, python ve diğerlerinden daha hızlı kullanılır. Ben ve / ve ayrıştırıcı lib'ler hxselectarasında iyi bir orta yol olduğunu düşünüyorum . sedawk
Thor

1
İşe yararsa bu harika! Sadece bir tür ayrıştırıcı kullanmamı önerdiğim için TechJack için bir uyarı ekliyordum;
goldilock

Thor, hxselectiyi görünüyor, kesinlikle daha fazlasını keşfedecek. Teşekkürler.
TechJack

@goldilocks: hxnormalizeiyi şekillendirilmemiş html / xml dosyalarına özen gösterir.
tokland

5

Varsa ruby, aşağıdakileri yapabilirsiniz

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

filegiriş html dosyanız nerede . Komut, Ruby bir liner'ı çalıştırır. İlk önce, tüm satırları okur fileve bunları bir dizgeye bağlar readlines.join. Daha sonra dizgiden bir şey seçer (ancak dahil değil) <tr>ve <\/tr>bu yeni karakterlerden bağımsız olarak bir karakter veya daha uzun olur [/(?<=<tr>).+(?=<\/tr>)/m]. Ardından, herhangi bir dizgeden <tr>veya </tr>dizeden kaldırılır gsub(/<\/?tr>/, "")(iç içe tretiketleri işlemek için gereklidir ). Sonunda dizeyi yazdırır puts.

Bir html ayrıştırıcısının sizin için garanti edilmediğini, ancak Nokogiri'yi birlikte kullanmanın çok kolay olduğunu rubyve komutu daha kolay hale getirdiğini söylediniz .

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

-rnokogiriNokogiri'yi yüklüyor. Nokogiri::HTML(readlines.join)tüm satırlarını okur file. xpath("//tr")her tröğeyi map { |e| e.content }seçer ve her öğenin içeriğini seçer, yani <tr>ve arasında olanı seçer </tr>.


1

grep

trEtiket içindeki içeriği birden fazla satır boyunca almak için, xargsönce bunu iletin , örneğin:

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

Yalnızca iç HTML’yi döndürmek için şunu kullanın:

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

perlreGenişletilmiş modeller için sözdizimini kontrol edin .

Not: Daha hızlı performans için ripgrephangisinin benzer bir sözdizimine sahip olduğunu düşünebilirsiniz .


Xargs olmadan bakarak egrep -o kullanarak satır içi javascript bulmak için kullanışlı geldi hoş dışarı basılmış "<script * </ script>.?"
Andrew

0

pup

Kullanma örneği pup(hangisi CSS seçiciyi kullanır ):

pup -f myfile.html tr

Etiketleri, kullanmadan yalnızca metin yazdırmak için: pup -f myfile.html tr text{}.

İşte birkaç örnek curl:

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

xpup

xpupHTML / XML ayrıştırma için örnek (XPath'ı destekleyen):

xpup -f myfile.html "//tr"

0

hızlı bir <tr>s listesi ise bu yardımcı olabilir:

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

şerefe

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.