Ubuntu Suomen keskustelualueet
Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: jepael - 03.07.09 - klo:10.33
-
Moi,
tiedän että tän ongelman voi ratkaista muutamalla rivillä C tai C++ koodia, mutta olisiko jollain vinkkiä
kuinka jotain perusasennuksessa mukana tulevia työkaluja (dd tms) voisi käyttää
ongelman ratkaisemiseen siltä varalta, että joskus tätä operaatiota tehdessä ei ole kääntäjiä käytössä.
Eli mulla on kaksi binääritiedostoa, vaikkapa A ja B, ja nämä pitää yhdistää tiedostoksi C siten, että
vuorotellen luetaan tiedostosta A ja B.
Esimerkki:
Tiedosto A: 00 02 04 06 08
Tiedosto B: 01 03 05 07 09
Lopputulos: 00 01 02 03 04 05 06 07 08 09
-
Tehtävän voi varmaankin tehdä vaikka kuinka monella tavalla, mutta itse tekisin sen pythonilla. Python-tulkki tulee useimpien jakeluiden mukana (myös Ubuntu), etkä tarvitse kääntäjää.
Tee tiedosto skripti.py, johon tallennat seuraavan skriptin:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
A = open('tiedostoA', 'r')
B = open('tiedostoB', 'r')
C = open('tiedostoC', 'w')
sizeA = os.path.getsize('tiedostoA')
sizeB = os.path.getsize('tiedostoB')
i = 0
while i < sizeA or i < sizeB:
if i < sizeA-1:
A.seek(i)
C.write(A.read(1))
if i < sizeB-1:
B.seek(i)
C.write(B.read(1))
i += 1
Tämän jälkeen ajat sen: python skripti.py. Vaihda koodissa olevat tiedostojen nimet haluamiksisi.
EDIT: Tein vielä extrana skriptin, joka tekee asian toiseen suuntaan. Se siis pilkkoo C:n kahteen muuhun tiedostoon tavuittain:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
A = open('tiedostoA', 'w')
B = open('tiedostoB', 'w')
C = open('tiedostoC', 'r')
sizeC = os.path.getsize('tiedostoC')
i = 0
while i < sizeC:
C.seek(i)
A.write(C.read(1))
C.seek(i+1)
B.write(C.read(1))
i += 2
-
Jos tiedostot ovat sen kokoisia, että sopivat muistiin, voisi miettiä tämmöistäkin: imutetaan kumpikin listaksi muistiin ja käytetään zip()-funktiota liittämään ne halutulla tavalla yhteen. (Tätä ei ole kokeiltu, voi olla jokin buginpoikanen livahtanut joukkoon :))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
bytes1 = open('tiedostoA', 'r').read()
bytes2 = open('tiedostoB', 'r').read()
for b1, b2 in zip(bytes1, bytes2):
sys.stdout.write('%c%c' % (b1, b2))
-
Tee tiedosto skripti.py, johon tallennat seuraavan skriptin:
While-silmukassa olevat seek()-kutsut ovat turhia.
EDIT: Tein vielä extrana skriptin, joka tekee asian toiseen suuntaan. Se siis pilkkoo C:n kahteen muuhun tiedostoon tavuittain:
Jälleen turhia seek()-kutsuja ja lisäksi tuo kaatuu jos paloiteltavan tiedoston tavumäärä on pariton.
-
Kiitoksia tuosta python-totetutuksesta, joskin päätin sitten tehdä asian C++:lla (fstream) koska se oli asennettuna ja viiden minuutin homma sillä.
Ilmeisesti SRecord-niminen softa voisi myös osata tän kyseisen operaation, koska ainakin sillä voi jakaa binääritiedoston odd ja even tavuihin.
Eli samalla vaivalla jos jotain pitää asentaa, niin mahdollisimman vähän, ja C-kääntäjä on melkein joka paikassa kuitenkin. Jos ikinä haluan
tuota koodinpätkää julkaista niin muunnan sen sitten tavalliselle C-kielelle. Muistaakseni Ubuntu 9.04:ssa ei ollut C++ kääntäjää esiasennettuna.
Tosiaan tiedostot ovat kymmenien kilotavujen luokkaa, samankokoisia ja parillisia kooltaan - itsekin luin tiedostot kahteen bufferiin, yhdistin kolmanteen bufferiin ja kirjoitin sitten levylle.
-
Jos ikinä haluan tuota koodinpätkää julkaista niin muunnan sen sitten tavalliselle C-kielelle. Muistaakseni Ubuntu 9.04:ssa ei ollut C++ kääntäjää esiasennettuna.
Varmaankaan ei ole sitä C:täkään (tuskin mitään muutakaan)... ::)
-
Tein aikana kuluksi Rubyllä toimivan version. Yhdistetyssä datassa ovat aina kaikki tiedostoA:n tavut. Jos tiedostoB on suurempi kuin tiedostoA niin ylimääräiset tiedostoB:n tavut tiputetaan pois. Yhdistetty data kirjoitetaan stdout:iin.
$ ruby -e 'print File.new("tiedostoA").read.split(//).zip(File.new("tiedostoB").read.split(//))'
Pythonin zip()-funktio tulostaa molemmista tiedostoista korkeintaan pienemmän tiedoston tavumäärän mukaisen määrän tavuja.
$ python -c 'print "".join(map("".join, zip(file("tiedostoA").read(), file("tiedostoB").read()))),'
-
Pythonin zip()-funktio tulostaa molemmista tiedostoista korkeintaan pienemmän tiedoston tavumäärän mukaisen määrän tavuja.
Totta, mutta esimerkeissä ”tiedostot” olivat samanmittaisia. Helppohan se on lisätä siihen tarvittaessa ensin pituusvertailu, jonka tuloksen perusteella pidemmän listoista loppuosa ulostetaan zip()-kutsun perään.
-
Pythonin zip()-funktio tulostaa molemmista tiedostoista korkeintaan pienemmän tiedoston tavumäärän mukaisen määrän tavuja.
Totta, mutta esimerkeissä ”tiedostot” olivat samanmittaisia. Helppohan se on lisätä siihen tarvittaessa ensin pituusvertailu, jonka tuloksen perusteella pidemmän listoista loppuosa ulostetaan zip()-kutsun perään.
Toki, ja mielestäni tuo Pythonin toimintatapa on tässä yhteydessä parempi kuin Rubyn vastaava.