Script írása -segítség kérés-

Sziasztok.

A legtöbb dolgot megoldottam eddig különböző script nyelveken, de most elakadtam.

Van két forrásom (m3u-k):

Egyik:

#EXTINF:0, Vegyes - m1
http://192.168.1.10:8001/1:0:1:778D:2C2:600:E080000:0:0:0:
#EXTVLCOPT:program=4040
#EXTINF:0, Vegyes - M1 HD
http://192.168.1.10:8001/1:0:1:FC8:D:1:E082E2F:0:0:0:
#EXTVLCOPT:program=30607
#EXTINF:0, Vegyes - m2 / Petofi
http://192.168.1.10:8001/1:0:1:778F:2C2:600:E080000:0:0:0:
...

(A fájl ugyanilyen formában folytatódik tovább )

Másik:

#NAME Tvheadend Channels
#SERVICE 1:0:0:0:0:0:0:0:0:0:http%3A%2F%2F192.168.1.11%3A9981%2Fstream%2Fchannelid%2F208258153&profile=pass:m1
#DESCRIPTION m1
#SERVICE 1:0:0:0:0:0:0:0:0:0:http%3A%2F%2F192.168.1.11%3A9981%2Fstream%2Fchannelid%2F99578265&profile=pass:m2 / Petofi
#DESCRIPTION m2 / Petofi
...

(A fájl ugyanilyen formában folytatódik tovább )

Arra keresnék valami megoldást, hogy ilyen végeredményt kapjak:


#NAME Tvheadend Channels
#SERVICE 1:0:1:778D:2C2:600:E080000:0:0:0:http%3A%2F%2F192.168.1.11%3A9981%2Fstream%2Fchannelid%2F208258153&profile=pass:m1
#DESCRIPTION m1
#SERVICE 1:0:1:778F:2C2:600:E080000:0:0:0:http%3A%2F%2F192.168.1.11%3A9981%2Fstream%2Fchannelid%2F99578265&profile=pass:m2 / Petofi
#DESCRIPTION m2 / Petofi

Tehát a megfelelő sorokban a " 1:0:0:0:0:0:0:0:0:0 " részt kellene az ezzel megfelelő másik fájl sorából cserélni.
A csatornák nevei azonosak, így az alapján összerendelhetőek.

Hogyan lehetne ezt egy scriptből megoldani, aminek megadom két fájlt és szépen összerendeli és kiköpi egy harmadikként az eredményt.

Köszönöm

Hozzászólások


awk -F' - |:[0-9]+/' 'FILENAME=="f1" { if (/^#EXTINF/) chn=$NF; if (/^http:/) chg2id[chn] = $NF; next }; /^#SERVICE/ { line = $0; next}; /^#DESCRIPTION/ { chn = substr($0,14); sub( /^#SERVICE 1:(0:)+/, "#SERVICE " chg2id[chn], line); print line; print $0; next} { print }' f1 f2

Ahol f1 és f2 _sorrendhelyesen_ a két fenti formájú fájl neve, és feltételezve, hogy a forma tényleg folytatódik.

Váó! Ez igen, nem is gondoltam, hogy egy sorban ezt így meg lehet oldani! Le a kalappal! Köszönöm.
Annyit esetleg lehetne szépíteni rajta, hogy azoknál a neveknél, aminek nincs párja a másik fájlban, ne törölje a " 1:0:0:0:0:0:0:0:0:0 " részt, csak egyszerűen ugorja át? Mert ezesetben a végeredményen futtathatnék még egy cserét másik bemeneti fájllal (most ugye törli azoknak a soroknak az elejéről a " 1:0:0:0:0:0:0:0:0:0 " -t így még egyszer nem tudom végigfuttatni rajta a cserét).

Isten áldjon. Köszönöm még egyszer.

<= Powered By Ubuntu & Gentoo Linux =>

'Software is like sex: It's better when it's free!'
By Linus Torvalds

Szívesen!

Amikor előáll a formátum kapcsán ez a "nincs párja", akkor felvetődik, hogy "hogyan nincs párja? már #DESCRIPTION rekord sincs? vagy van, de üres? és biztos, hogy rögtön követi a #SERVICE rekordot?", és csupán ennek a bizonytalanságnak a kivédése _alapvetően_ változtatja meg a megközelítést és így a kódot.

https://pastebin.com/wGwHsfmH

Megkérhetlek, hogy magyarázd el, mi ez?
Régen sokat használtam awk-t, de csak a primitív funkcióit.
Maga a script rész még so so érthető, habár a $NF-t már ki kellett próbálni, annyira beálltam a perl szintaxisra :)

Szóval az elsődleges problémám a -F értelmezése... a teljes regexre illeszkedő minta lesz a szeparátor??

A -F (FS változó értéke) ugyanolyan re-ként értelmezett, mint bárhol másutt. Ha vagylagosság (OR, nem XOR!) van benne, akármelyik alternatíva illeszkedése mezőt határol, ahol illeszkedik.

Itt arra használtam fel, hogy a lényeges rekord megtalálása után ne kelljen külön sztringfüggvénnyel darabolni a rekordot a keresett adat kiemeléséhez.

#EXTINF:0, Vegyes - m1
-- ilyen sor tartalmazza a csatornának azt az azonosítóját (itt: "m1"), ami a másik fájlban kulcsként használható. Ha azt mondom, hogy határold a " - " regexp (gyakorlatilag: sztring) mentén a mezőker, akkor az utolsó mező ($NF) értéke lesz az azonosító. Tkp. a $2 is ugyanezt jelenti, ha a megadott fájldarab jellemző az egészre. Másrészt ha akad olyan rekord, ahol a sor végén akár csak egy szóköz van, és a másik fájlban ez a szóköz nincs a csatornaid végén, az egész bukott.

http://192.168.1.10:8001/1:0:1:778D:2C2:600:E080000:0:0:0:
-- az ilyen alakú sorok utolsó /-jele után van a becserélendő sztring. Ha azt írom elő, hogy a darabolás olyan minta alapján történjen, ami a ":" + portszám + "/"- re illeszkedik (:[0-9]+/), akkor ebben a sorban is a $NF (vagy $2) értéke lesz a keresett adat.
A minta egyébként túlhatározott: a fájldarab szerint már a "[0-9]/" minta is elég volna.

A két FS lehetőséget csak összevontam a -F' - |:[0-9]+/' paraméterrel. Hogy a többi rekordot is szétdarabolja egy ilyen minta mentén, az a feladat szempontjából irreleváns.

Egyébként a megoldás alapja az éppen feldolgozás alatt álló fájl nevének (FILENAME) kiaknázása: ha az értéke "f1" akkor tudom, hogy kulcsot és ahhoz tartozó cseresztringet keresek, minden egyéb műveletet át is ugrok (next).

Ha a FILENAME nem "f1", akkor a többi kódrész jut szóhoz.
Ez feltölt egy tömböt f2 soraival. Megjegyzi, hogy hol volt #SERVICE rekord. Ha azután talál valahol az adott csatornaid alapján a cseresztringet a cserélendő helyére #DESCRIPTION mezőben, visszalép a tömb megfelelő sorára és cserél.
Ha a következő #SERVICE rekordig nincs #DESCRIPTION rekord, vagy üres az ott jegyzett csatornaid, akkor nem lesz csere.

F2 végigolvasása után kijön a kimenetre, ami a sorok tömbjébe bekerült és ott módosult vagy maradt.

Szia.

Igen, abban az esetben vehetjük úgy, hogy nincs #DESCRIPTION rekord sem. Sok esetben azért áll elő ez a helyzet mert más a név (tehát van #DESCRIPTION rekord és minden csak nem illeszkedik rá a minta a név nem egyezősége miatt), vagy más esetben csak egyszerűen nincs abban a fájlban párja. Ilyen esetekben lefuttatnám egy másik fájllal is és ha abban van illeszkedés onnan beilleszteném a párokat.

És köszönöm a magyarázatot is, hozzá, nagyon tanulságos!

<= Powered By Ubuntu & Gentoo Linux =>

'Software is like sex: It's better when it's free!'
By Linus Torvalds

Egyébként ha az egyszerűbb, az is megfelelő, ha a futás után a "#SERVICE http" részeket (ezek ahol nem volt illeszkedés) egyszerűen visszahelyettesítjük "#SERVICE 1:0:0:0:0:0:0:0:0:0:http" -vel, így a következő futásnál ha van illeszkedés azok is cserélve lesznek. Ha ezt egyszerű megcsinálni, azt megköszönöm, ha nem, akkor ezt kézzel megcsinálom, maga a többi már nagyon nagy segítség!

<= Powered By Ubuntu & Gentoo Linux =>

'Software is like sex: It's better when it's free!'
By Linus Torvalds

Most látom, hogy nem lesz jó a gondolatom, mert a 2. futásnál a jó sorokat is elrontja, mert van hogy az eleje illeszkedik. Ezt úgy lehetne kivédeni, hogy az illeszkedési minta legyen pont 1:0:0:0:0:0:0:0:0:0: mert most ha jól látom (értelmezem) ez "1:(0:)+" és erre az 1:0:1:778D:2C2:600:E080000:0:0:0: is illeszkedik, emiatt az eredmény a 2. futás után 1:778D:2C2:600:E080000:0:0:0: lett.
Ezt módosítva ez a része így rendben van (teszteltem).

<= Powered By Ubuntu & Gentoo Linux =>

'Software is like sex: It's better when it's free!'
By Linus Torvalds