Ubuntu Suomen keskustelualueet

Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: jepael - 03.07.09 - klo:10.33

Otsikko: Tiedostojen yhdistäminen tavuittain
Kirjoitti: 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

Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: Ape3000 - 03.07.09 - klo:11.27
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:
Koodia: [Valitse]
#!/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:
Koodia: [Valitse]
#!/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
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: SuperOscar - 03.07.09 - klo:12.22
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 :))

Koodia: [Valitse]
#!/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))
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: mgronber - 04.07.09 - klo:09.12
Tee tiedosto skripti.py, johon tallennat seuraavan skriptin:

While-silmukassa olevat seek()-kutsut ovat turhia.

Lainaus
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.
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: jepael - 06.07.09 - klo:12.25
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.
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: Tomin - 06.07.09 - klo:12.29
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)... ::)
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: mgronber - 07.07.09 - klo:20.25
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.

Koodia: [Valitse]
$ 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.

Koodia: [Valitse]
$ python -c 'print "".join(map("".join, zip(file("tiedostoA").read(), file("tiedostoB").read()))),'
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: SuperOscar - 07.07.09 - klo:20.28
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.
Otsikko: Vs: Tiedostojen yhdistäminen tavuittain
Kirjoitti: mgronber - 07.07.09 - klo:20.38
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.