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
- 1621 megtekintés
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.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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 hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Affene... tényleg jobb, ha többé a saját gépeimhez se nyúlok.
Mióta megjelent a hozzászólásod, azóta töprengtem, hogy hogy a fba illik a képbe a szeparátorban lévő ' - |'. Meg sem fordult a fejemben, hogy a | = OR... :(
Köszi.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni