Kirjoittaja Aihe: Tiedostojen yhdistäminen tavuittain  (Luettu 3082 kertaa)

jepael

  • Käyttäjä
  • Viestejä: 2
    • Profiili
Tiedostojen yhdistäminen tavuittain
« : 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


Ape3000

  • Käyttäjä
  • Viestejä: 27
    • Profiili
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #1 : 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
« Viimeksi muokattu: 03.07.09 - klo:11.34 kirjoittanut Ape3000 »

SuperOscar

  • Käyttäjä
  • Viestejä: 4013
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #2 : 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))
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

mgronber

  • Käyttäjä
  • Viestejä: 1458
    • Profiili
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #3 : 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.

jepael

  • Käyttäjä
  • Viestejä: 2
    • Profiili
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #4 : 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.

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11473
    • Profiili
    • Tomin kotisivut
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #5 : 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)... ::)
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

mgronber

  • Käyttäjä
  • Viestejä: 1458
    • Profiili
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #6 : 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()))),'

SuperOscar

  • Käyttäjä
  • Viestejä: 4013
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #7 : 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.
pöytäkone 1, NUC: openSUSE Leap 15.6, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

mgronber

  • Käyttäjä
  • Viestejä: 1458
    • Profiili
Vs: Tiedostojen yhdistäminen tavuittain
« Vastaus #8 : 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.