Kivágás fileból szkript segítségével

Fórumok

Sziasztok!

Bocsi a kérdésért, már biztosan volt itt a hupon de most egyszerűen nem találom. Az lenne a feladat, hogy kb. 150 fileból kellene kivágni egy megadott tagek kozti reszt es ezeket mondjuk betenni egy txt fileba.
Nagyon szepen koszonom a segitseget!
üdv,
s.

Hozzászólások

Ez csak 1 sorra működik, nem?

Több sorra talán a legegyszerűbb a következő (a sed oneliners-ből):

# print section of file between two regular expressions (inclusive)
sed -n '/<p>/,/<\/p>/p' # case sensitive 

Viszont ez a fájlban előforduló legelső nyitó tag-től az előforduló utolsó záró tag-ig vágja ki a fájlból a sorokat.

Egy fokkal jobb megoldás (írjunk ciklust sedben...):

sed -n '
    /<p>/i!b
    :a
    /<\/p>/!{
        N
        ba
    }
    s/.*<p>//gi
    s/<\/p>.*//gi
    p
    q'

Ez eltávolítja a nyitó és záró taget is. Viszont csak a legelső nyitó tagtől a legelső záróig vágja ki a sorokat, tehát az esetleges egymásba ágyazott tageket nem kezeli okosan.

Kis kipofozással sztem javítható lenne. (nekem nem volt rá szükségem, mikor ezt írtam)

Üdv,
kl223

A második példáddal nem küzdök, de elmagyaráznád, hogy ezt honnan vetted: "Viszont ez a fájlban előforduló legelső nyitó tag-től az előforduló utolsó záró tag-ig vágja ki a fájlból a sorokat." Mert nem igaz.

Az elején nem nyomtat (a -n opció miatt), ez után az első nyitó TAG-től az ezt követő első záró TAG-ig nyomtat (ez meg a p parancs miatt van), aztán megint nem nyomtat, majd ha lát megint nyitó TAG-et akkor újfent elkezd nyomtatni, és ha ez után lát záró TAG-et, megint abbahagyja, és így tovább.

man sed:

q: Immediately quit the sed script without processing
any more input, except that if auto-print is not disabled
the current pattern space will be printed.

Javíts ki, ha vmit félreértelmeztem volna, de amint egyszer eljut a 'q' parancsig a vezérlés, a sed leáll. Tehát az első nyitó tagtől az első záróig fut.

kl223

dd if=[bemeneti fájlod] bs=1 skip=[honnan kezdje az olvasást, a beneneti fájl elejéhez képest] count=[hány 'bs'-nyi bájtot olvasson a fájlból.]

pl.:

dd if=/dev/hda bs=1 skip=512 count=152 | hexdump

akkor a winyód(hda) második szektorát fogod látni. (a második 512 bájt.)

szerk: kacsacsőrök nem láttszóttak. De látom másra gondoltá
l.

Én a sed környékén néznék körbe a helyedben ;)...

A gawk lesz a te barátod. Ha pl. a tag

<metadata>

és

</metadata>

akkor:


cat infile | gawk -F\> '
BEGIN { valt = 0; } 
{ 
    volt=0;
    for (i=1;(i<=NF);i++) {
        if ($i ~ /<metadata/) { valt ++; }
        if (valt>0) { 
            if ($i!="") {
                volt=1; 
                printf("%s>", $i);
            }
        }
        if ($i ~ /<\/metadata/) { valt = valt -1; }
    }
    if(volt>0) {
        printf("\n");
    }
}' > outfile

valt : számlálja a beágyazott tag-eket.
volt : figyeli, hogy egy sorban volt-e kiprintelendő szó, mert ha volt, kell egy újsor karakter a végére

persze, ha olyan tag-ek is kellenek, aminek nincs zárója (pl:

<metadata valamilyen adatok>

)
akkor a dolog további gondolkodást igényel :-)

javasolt olvasmány: man gawk

--
Viszlát, és kösz a halakat!

szerintem ez lesz a te baratod:

cat akarmi.txt | awk '/from_tag/,/to_tag/'

Annyiban megfelelőbb a script, hogy ha a from_tag előtt és/vagy a to_tag után is van adat a kérdéses sorban, akkor a "rövid" változat azokat nem vágja le... A script viszont minden esetben helyesen működik, és csak a tagek közötti részt (és a tageket) hozza.

--
Viszlát, és kösz a halakat!