Kirjoittaja Aihe: (Kahden) Tiedoston lukua rivi kerrallaan [ Ratkaistu ]  (Luettu 7380 kertaa)

mikk0

  • Käyttäjä
  • Viestejä: 555
    • Profiili
Yritin luoda skriptin, jolla saan olemassaolevasta ubuntuguiden suomennoksesta ja vastaavasta englanninkielisestä versiosta rakennettua sed-skriptin, jonka avulla taas saan uusimman version päivitettyä hujauksessa suomenkieliseksi (saa nähdä tuleeko noita enää, vai kyllästyikö tekijä jo projektiin...). Käsin näiden muutosten toteuttaminen on liian hankalaa, joten tämä automatisointi olisi ihan mukavaa.
Lisäksi tässä oppii yhtä ja toista skriptauksesta ja varsinkin sedistä, joka on todella pätevä työkalu.

Kaikki muu sujuu hienosti, mutta seuraava ongelma minulla on:

Skriptin pitäisi lukea rivi samaan tahtiin ensin englanninkielisestä versiosta rivi ja vastaava rivi suomenkielisestä tiedostosta ja kirjoittaa nuo rivit peräkkäin kolmanteen tiedostoon.
En keksinyt tähän muuta kuin while-loopin jossa tämä hoidetaan rivinumeroa kasvattamalla ja käytetään head ja tail -ohjelmia.

Tämä on riittävän nopea ratkaisu minulle, mutta ongelmana on se, että jossain vaiheessa looppi hyppää yhden rivin yli tuossa englanninkielisessä tiedostossa! En ymmärrä.

Tässä tuo looppi ja pätkät sekä englanninkielistä tiedostoa että vastaavat rivit suomenkielisestä ja vielä tuo tuloste:
looppi:
Koodia: [Valitse]
i=1
lines=`wc -l "$infile1" | awk '{print $1}'`
echo "Total lines to go: $lines"

while [ $i -le $lines ]
do
  head -n $i "$infile1" | tail -n 1
  head -n $i "$infile2" | tail -n 1
  if ! (( "$i" % 100 ))
  then
    echo "line $i" >&2
  fi
  let "i += 1"
done >> "$outfile"

englanninkielinen tiedosto, rivit 391-398:
Koodia: [Valitse]
sudo gnome-clipboard-daemon &
System -> Preferences -> Sessions
Sessions
Startup Programs Tab ->
Add
Startup Command:
gnome-clipboard-daemon
Order:

suomenkielinen tiedosto, rivit 391-398:
Koodia: [Valitse]
sudo gnome-clipboard-daemon &
Järjestelmä -> Asetukset -> Istunnot
Istunnot
Käynnistyvät ohjelmat-välilehti ->
Lisää
Käynnistyskomento:
gnome-clipboard-daemon
Järjestys:

Tällaisen tuloksen tuo skripti tuottaa:
Koodia: [Valitse]
...
System -> Preferences -> Sessions
Järjestelmä -> Asetukset -> Istunnot
Sessions
Istunnot
Startup Programs Tab ->
Käynnistyvät ohjelmat-välilehti ->
Lisää
Startup Command:
Käynnistyskomento:
gnome-clipboard-daemon
gnome-clipboard-daemon
...

Eli siis tuo Add-rivi tippuu pois. Joka kerta! Mitään muuta tiedostosta ei jää pois. Itse rivissä ei ole mitään outoa, sillä jos muutan lähdetiedostoja, niin sitten se on joku toinen rivi joka sieltä tippuu. Mutta aina vain yksi ja aina tuosta englanninkielisestä tiedostosta.
Nämä lähdetiedostotkin ovat jo valmiiksi muokattuja, esim. ylimääräiset rivinvaihdot ja html-tagit on karsittu pois, yms.

Jos joku näkee tässä jonkun pahan virheen, niin ilmoittakaa ihmeessä.
Tai jos tiedätte fiksumman tavan lukea tiedostoa riveittäin, niin olisin kiinnostunut kuulemaan moisesta.
Kokeilin myös korvata tuon head/tail -hässäkän sedillä (sed -n -e "$i p" "$infile1"), mutta se käyttäytyi aivan samalla tavalla, eli kyseessä on jokin outous tuossa itse silmukassa. Lisäksi vauhti hidastui aivan tolkuttomasti.

Yritin käyttää myös read:ia tiedoston lukemiseen, mutta se lukee vain ensimmäisen rivin yhä uudelleen, ellei se ole while-loopin testiosassa ja tuolloin en pysty tuota toista tiedostoa lukemaan samanaikaisesti samalla metodilla.

Mikko
« Viimeksi muokattu: 09.11.05 - klo:11.12 kirjoittanut mikk0 »

Mikko Saarinen

_Pete_

  • Käyttäjä
  • Viestejä: 1836
  • Fufufuuffuuu
    • Profiili
Re: Tiedoston lukua rivi kerrallaan?
« Vastaus #1 : 01.11.05 - klo:09.35 »
Yritin luoda skriptin, jolla saan olemassaolevasta ubuntuguiden suomennoksesta ja vastaavasta englanninkielisestä versiosta rakennettua sed-skriptin, jonka avulla taas saan uusimman version päivitettyä hujauksessa suomenkieliseksi (saa nähdä tuleeko noita enää, vai kyllästyikö tekijä jo projektiin...). Käsin näiden muutosten toteuttaminen on liian hankalaa, joten tämä automatisointi olisi ihan mukavaa.
Lisäksi tässä oppii yhtä ja toista skriptauksesta ja varsinkin sedistä, joka on todella pätevä työkalu.

Kaikki muu sujuu hienosti, mutta seuraava ongelma minulla on:

Skriptin pitäisi lukea rivi samaan tahtiin ensin englanninkielisestä versiosta rivi ja vastaava rivi suomenkielisestä tiedostosta ja kirjoittaa nuo rivit peräkkäin kolmanteen tiedostoon.
En keksinyt tähän muuta kuin while-loopin jossa tämä hoidetaan rivinumeroa kasvattamalla ja käytetään head ja tail -ohjelmia.

Tämä on riittävän nopea ratkaisu minulle, mutta ongelmana on se, että jossain vaiheessa looppi hyppää yhden rivin yli tuossa englanninkielisessä tiedostossa! En ymmärrä.


Siinä hyvässä oppaassa (abs-guide), jota itse mainostit on esimerkkejä miten tuo tapahtuu :)


mikk0

  • Käyttäjä
  • Viestejä: 555
    • Profiili
Re: Tiedoston lukua rivi kerrallaan?
« Vastaus #2 : 01.11.05 - klo:11.04 »
Siinä hyvässä oppaassa (abs-guide), jota itse mainostit on esimerkkejä miten tuo tapahtuu :)

Joo. Tuota on kyllä tullut kelattua edes takaisin, mutta en vielä ole tällaista löytänyt.
Yhtä tiedostoa kerrallaan jos luetaan, niin siinä kyllä toimii esim read while-loopissa, mutta kun luetaan kahta tiedostoa, niin eipä taida tällainen enää onnistuakaan.

Mikko

Mikko Saarinen

_Pete_

  • Käyttäjä
  • Viestejä: 1836
  • Fufufuuffuuu
    • Profiili
Re: Tiedoston lukua rivi kerrallaan?
« Vastaus #3 : 01.11.05 - klo:11.26 »
Siinä hyvässä oppaassa (abs-guide), jota itse mainostit on esimerkkejä miten tuo tapahtuu :)

Joo. Tuota on kyllä tullut kelattua edes takaisin, mutta en vielä ole tällaista löytänyt.
Yhtä tiedostoa kerrallaan jos luetaan, niin siinä kyllä toimii esim read while-loopissa, mutta kun luetaan kahta tiedostoa, niin eipä taida tällainen enää onnistuakaan.

Mikko

abs-guide:

11-7. Using read with file redirection

  24 exec 3<> myfile.txt
  25 while read line <&3
  26 do {
  27   echo "$line"
  28   (( Lines++ ));                   #  Incremented values of this variable
  29                                    #+ accessible outside loop.
  30                                    #  No subshell, no problem.
  31 }
  32 done
  33 exec 3>&-


Tuota soveltamalla,  eli karkeasti:


exec 3<> myfile1.txt
exec 4<> myfile2.txt
do {
  read line1 <&3
  read line2 <&4

 // loopista pitää jotenkin päästä pois ...
}
done

exec 3>&-
exec 4>&-


Niin ja en ole tuollaista ikinä oikeasti kokeillut enkä muutenkaan pahemmin bashaillut ...

mikk0

  • Käyttäjä
  • Viestejä: 555
    • Profiili
Re: Tiedoston lukua rivi kerrallaan?
« Vastaus #4 : 05.11.05 - klo:14.10 »
No nyt alkoi valoa kajastaa tähänkin ongelmaan.

Eli skripti ei tiputakaan yhtä riviä pois, vaan itse asiassa kaikki joilla esiintyy vain ja ainoastaan sana Add.
Näitä on useampiakin alkuperäisessä englanninkielisessä tiedostossa, mutta ei yhtään tuossa $outfile:ssä.

Sen kun ymmärtäisi vielä että miksi rivi jää tulostumatta tiedostoon, niin hyvä olisi. Liekö tuo jokin varattu sana joka häiriköi looppia, vai mistä on kyse? Vaikuttaa hieman mystiseltä.

Mikko

Edit: ei ehkä sittenkään, sillä tuosta jäi kaikkiaan 117 riviä tekstiä pois.
Sovellan Peten vinkkiä ja jotain positiivisia tuloksia on saatu  ;D

Edit 2: :-[ Nyt hävettää:

Syy siihen miksi minun skriptini tiputti nuo 117 riviä pois (mukaan lukien Lue ja Add -rivit) on tässä
Koodia: [Valitse]
sed -i -e '/^--$/d' -e '/^...$/d' "$outfile"
Tämän piti poistaa rivit, joissa on vain merkit -- tai ... (grep lisää ensimmäisen, ja tuo jälkimmäinen nyt on muuten aivan turha). Kuitenkin nuo kolme pistettä täsmäävät mihin tahansa kolmeen merkkiin, esimerkiksi Add, tai Lue...
Eli ne olisi pitänyt laittaa muodossa \.\.\.  :-[
« Viimeksi muokattu: 10.11.05 - klo:08.56 kirjoittanut mikk0 »

Mikko Saarinen

mikk0

  • Käyttäjä
  • Viestejä: 555
    • Profiili
Re: (Kahden) Tiedoston lukua rivi kerrallaan [ Ratkaistu ]
« Vastaus #5 : 09.11.05 - klo:11.20 »
No nyt, no nyt  ;D :D ;D

Koodia: [Valitse]
exec 3<>"$infile1"
exec 4<>"$infile2"

while read line1 <&3 && read line2 <&4
do
  echo "$line1"
  echo "$line2"
done  >> "$outfile"

exec 3>&-
exec 4>&-

Tämä koodinpätkä avaa kaksi tiedostoa (määritelty muuttujissa infile1 ja infile2) ja lukee molemmista yhden rivin kerrallaan ja kirjoittaa nuo rivit peräkkäin tiedostoon, joka on määritelty muutujassa outfile.

Tässä versiossa ei tarvita enää mitään laskuria (i) kertomaan käyttäjälle kuinka monta riviä on käsitelty, sillä tämä on hurjan paljon nopeampi kuin aiemmat viritelmäni, eikä tuhlaa enää minuuttia noiden n. 6500 rivin käsittelyyn.

Mikko

P.S. Kiitos Petelle että ohjasit oikealle tielle.  :D
Tuo ei kuitenkaan olisi toiminut ehdottamallasi tavalla, sillä jos read-lause on loopin sisällä, se lukee aina tiedoston ensimmäisen rivin, eikä joka kerta uutta riviä. Mutta nyt kun read on silmukan ehto-osassa, niin tämä homma toimii.

Mikko Saarinen