Kirjoittaja Aihe: Pieni scriptausongelma - apuva [RATKAISTU]  (Luettu 3348 kertaa)

tjka

  • Käyttäjä
  • Viestejä: 144
    • Profiili
Pieni scriptausongelma - apuva [RATKAISTU]
« : 04.03.09 - klo:13.28 »
Moi !

Osaisiko joku auttaa lukujen tutkimisessa kun mulla yksinkertaisesti loppuu taidot...  :-[

Jos muuttujan arvon sisältö näyttää seuraavanlaiselta...

 + 6
- 11
   0
   0
 - 2

..niin kuinka saisin tutkittua onko siinä lukuja jotka ovat suurempia kuin +5 tai pienempiä kuin -5 ?
Pelkkä tieto tästä riittäisi.

Rivejä voi olla epämääräinen lukumäärä.
Jokaisella rivillä on 4 merkkiä, jonka jälkeen rivinvaihto.
Tuo muuttujan arvo on "grep"attu suuremmasta kokonaisuudesta ja siitä tuloksesta kelpuutettu vain rivin 4 viimeistä merkkiä.
Näin pitkälle siis pääsin "Googlaamalla" ja parin kaverin vihjeillä mutta sitten tökkäs...  :'(


-tjka-

« Viimeksi muokattu: 06.03.09 - klo:11.19 kirjoittanut tjka »

snifi

  • Vieras
Vs: Pieni scriptausongelma - apuva
« Vastaus #1 : 04.03.09 - klo:15.48 »
Helpoin varmaan tehdä Pythonilla, voit itse vaihtaa tiedostonnimet, ehdot ja tulostuksen oikeanlaiseksi:

Koodia: [Valitse]
#!/usr/bin/python

filename="test001.txt"
f=open(filename)
lines=f.readlines()
for r in lines:
  t=""
  for c in r:
    if c in "1234567890+-":
      t+=c
  try:
   i=int(t)
   if i < -5 or i > 5:
     result="bigger than 5 or less than -5"
   else:
     result="between -5 and 5"
  except ValueError:
   result="not a number"
  #print "%s: %s"%(t,result)
  print result

UbunTux

  • Käyttäjä
  • Viestejä: 2046
  • KubunTux
    • Profiili
Vs: Pieni scriptausongelma - apuva
« Vastaus #2 : 04.03.09 - klo:16.25 »
jotain tämmöistä
Koodia: [Valitse]
sed -n 1p tiedostonappaa ensimmäisen rivin jne.
Koodia: [Valitse]
if [  "$jotain" -gt 5 ] ; then
jotain
fi
tarkistaa onko luku suurempi kuin 5. -lt saat pienemmät kuin 5 jne
« Viimeksi muokattu: 04.03.09 - klo:16.30 kirjoittanut UbunTux »
KDE neon
Uudempaa KDE:tä Ubuntulla

tjka

  • Käyttäjä
  • Viestejä: 144
    • Profiili
Vs: Pieni scriptausongelma - apuva
« Vastaus #3 : 04.03.09 - klo:16.28 »
Kiitos Snifi.
Kokeilen huomenna, mutta toimiiko tuo koska muuttuja on formaatissa "plusvälilyöntinumero" ( + 6)  tai "miinusvälilyöntinumero" (- 2) ?

Toinen asia.
Unohdin mainita että väkerrän tuota scriptiä #!/bin/bash muodossa, joten voiko bash scriptin sisältä käynnistää hetkeksi python scriptin?

Kiitos myös UbunTuxille. Tutkin huomenna...

-tjka-

peran

  • Vieras
Vs: Pieni scriptausongelma - apuva
« Vastaus #4 : 04.03.09 - klo:16.32 »
Kyllä minusta näyttäisi toi snifin ehdotus toimivan niissäkin tapauksissa. Tosin en testannut, mutta algoritmi näyttäisi ottavan nekin huomioon.

SuperOscar

  • Käyttäjä
  • Viestejä: 4064
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Pieni scriptausongelma - apuva
« Vastaus #5 : 04.03.09 - klo:17.23 »
Minä tekisin Pythonilla pikemmin näin:

Koodia: [Valitse]
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from sys import stdin

for rivi in stdin:
    try:
        luku = int(rivi)
    except ValueError:
        continue
    if -5 <= luku <= 5:
        print('-5:n ja 5:n välissä')
    else:
        print('Alle -5 tai yli 5')

Tuo ”!/usr/bin/env python” on suositeltu tapa Python-ohjelmien käynnistämiseen.

Muoks: Tuota siis käytetään antamalla tiedostonimi kulmasulkeen kera:

Koodia: [Valitse]
./skripti < tiedosto
Muoks 2: Tuli mieleen, kun en tiedä, mitä varsinaisesti teet... Jos sinua kiinnostaa vain, onko jokin luvuista alle -5 tai yli 5, ja jos tiedosto on niin pieni että sen voi lukea kerralla muistiin:

Koodia: [Valitse]
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from sys import stdin

if all([-5 <= int(s) <= 5 for s in stdin]):
    print('Kaikki luvut ovat väliltä -5...5')
else:
    print('Joukossa on lukuja, jotka ovat < -5 tai > 5')

Tuossa tulee jo kivasti demottua Pythonin vahvuuksia kuten ”list comprehensioneja” (mitä lienevätkään suomeksi) ja all()-funktiota.
« Viimeksi muokattu: 05.03.09 - klo:00.16 kirjoittanut SuperOscar »
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

tjka

  • Käyttäjä
  • Viestejä: 144
    • Profiili
Vs: Pieni scriptausongelma - apuva
« Vastaus #6 : 05.03.09 - klo:11.23 »
Kokeilin Snifin koodinpätkää ja se näyttää toimivan.
Muutin sitä muotoon...

   if i < -5 or i > 5:
     result="ERROR"
   else:
     result="OK"

Mutta kuinka (en osaa yhtään Pythonia) saan kirjoitettua tulokset johonkin uuteen tiedostoon?
Sitten on helppoa selvittää (grep) löytyykö tuosta tiedostosta yhtään "ERROR" sanaa ja jos löytyy niin sitten tehdään "jotain"...  ;)

Millä komennolla saan bash scriptin sisältä ajettua tuon python scriptin?
Käykö vain "python snifi.py" vai pitääkö määritellä muita asioita ???


-tjka-


SuperOscar

  • Käyttäjä
  • Viestejä: 4064
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Pieni scriptausongelma - apuva
« Vastaus #7 : 05.03.09 - klo:12.03 »
Mutta kuinka (en osaa yhtään Pythonia) saan kirjoitettua tulokset johonkin uuteen tiedostoon?

Avaamalla toinen tiedosto kirjoitusta varten.

Tosin jos haluat vain:

Lainaus
Sitten on helppoa selvittää (grep) löytyykö tuosta tiedostosta yhtään "ERROR" sanaa ja jos löytyy niin sitten tehdään "jotain"...  ;)

...niin jälkimmäinen ideani voisi toimia ihan hyvin, tulostaisit vain ”ERROR” siinä else-lausekkeessa. Muutenkin olisi skriptitasolla helpompaa käyttää uudelleenohjauksia kuin nimettyjä tiedostoja.

Lainaus
Millä komennolla saan bash scriptin sisältä ajettua tuon python scriptin?
Käykö vain "python snifi.py" vai pitääkö määritellä muita asioita ???

Pelkkä POLKU/snifi.py riittää, jos #!-rivi on paikallaan, missä POLKU osoittaa snifi.py-tiedoston sijaintiin (pelkkä piste riittää poluksi, jos se sijaitsee samassa hakemistossa kuin kutsuva skripti).
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

UbunTux

  • Käyttäjä
  • Viestejä: 2046
  • KubunTux
    • Profiili
Vs: Pieni scriptausongelma - apuva
« Vastaus #8 : 05.03.09 - klo:12.12 »
Koodia: [Valitse]
#!/bin/bash
tiedosto=$1

rivit=$(wc -l $tiedosto| awk '{ print  $1 }')
echo rivejä $rivit
a=1
until [ $a -eq $(expr $rivit + 1) ] ; do
  luku=$(sed -n "$a"p $tiedosto)
  if [ $luku -lt 5 ] && [ $luku -gt -5 ] ; then
    echo rivillä $a luku ei kuuluu joukkoon
  else
    echo rivillä $a luku kuuluu joukkoon
  fi
  a=$(expr $a + 1)
done

Noin bashilla eräällä tavalla. Tietysti python on nopeampi.
« Viimeksi muokattu: 05.03.09 - klo:12.26 kirjoittanut UbunTux »
KDE neon
Uudempaa KDE:tä Ubuntulla

snifi

  • Vieras
Vs: Pieni scriptausongelma - apuva
« Vastaus #9 : 05.03.09 - klo:12.37 »
Print-käskyllä tulostamasi rivit Python-ohjelmassa voit uudelleenohjata komentoriviltä tiedostoon:
Koodia: [Valitse]
python testaus.py >tiedosto.txt
Toinen mahdollisuus on avata tiedosto Python-ohjelmassa kirjoittamista varten, ja kerätä tuloste siihen, jotakuinkin näin:
Koodia: [Valitse]
f=open("tiedosto.txt", "w")
for n in lines:
  f.write(n)

Periaatteessa voit rakentaa kokonaisuuden joko niin että ohjaat komentoriviskriptillä Python-ohjelmaa tai vaihtoehtoisesti Python-ohjelmalla komentorivikäskyjä. Jälkimmainen tapa on syntaksinsa puolesta selkeämpi.

Käyttöjärjestelmäkomentojen antamiseksi Pythonista kaksi tärkeintä käskyä ovat os.popen() ja os.system(). Käytä ensimmäistä silloin kun käyttöjärjestelmäkutsu tulostaa tekstiä jonka haluat talteen, ja jälkimmäistä silloin kun pelkkä ohjelman käynnistyskäsky riittää. Käyttämällä tiedostoon kirjoittamista tulosteen välivarastointipaikkana selviät pelkästään os.system()-komennolla.

Tässä yksi esimerkki os.popen()-käskystä, jota voi käyttää lämpötilatiedon lukemiseen KWeatherService-ohjelmasta.

Koodia: [Valitse]
import os
lines=os.popen("dcop KWeatherService WeatherService temperature EFKK").readlines()
print lines

Toisaalla ohjelmassa on puolestaan käytetty os.system()-käskyä imagemagickin convert-komennon ohjaamiseen:

Koodia: [Valitse]
t=strftime("%Y-%m-%d-%H%M")
command = """
convert \( current.png degrees.png +append \) \
-background none -append rpics/vetero-%s.png
"""%t
os.system(command)


SuperOscar

  • Käyttäjä
  • Viestejä: 4064
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Pieni scriptausongelma - apuva
« Vastaus #10 : 05.03.09 - klo:12.49 »
Print-käskyllä tulostamasi rivit Python-ohjelmassa voit uudelleenohjata komentoriviltä tiedostoon:
Koodia: [Valitse]
python testaus.py >tiedosto.txt

Tuo on poistumassa oleva piirre.

Lainaus
Käyttöjärjestelmäkomentojen antamiseksi Pythonista kaksi tärkeintä käskyä ovat os.popen() ja os.system().

Samoin os.popen() on poistumassa oleva piirre :) Suositus on käyttää subprocess-moduulin funktioita.
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

tjka

  • Käyttäjä
  • Viestejä: 144
    • Profiili
Vs: Pieni scriptausongelma - apuva [RATKAISTU]
« Vastaus #11 : 06.03.09 - klo:11.18 »
Kiitos kaikille vastauksista... !!!
Koska alkuperäinen scriptini (jos sitä nyt scriptiksi voi edes kutsua  ;) ) on bashiä, niin päädyin lopulta kuitenkin yrittämään UbunTuxin esimerkillä...

#!/bin/bash
tiedosto=/home/tjka/temp.txt

rivit=$(wc -l $tiedosto| awk '{ print  $1 }')
echo rivejä $rivit
a=1
until [ $a -eq $(expr $rivit + 1) ] ; do
  luku=$(sed -n "$a"p $tiedosto)
  if [ $luku -lt 5 ] && [ $luku -gt -5 ] ; then
    echo rivillä $a luku ei kuuluu joukkoon
  else
    echo rivillä $a luku kuuluu joukkoon
  fi
  a=$(expr $a + 1)
done

Ongelma on ettei tuokaan toiminut ihan niinkuin pitäisi.
Eli tein kokeeksi seuravanlaisen tiedoston (temp.txt) ...

   0
- 13
   0
   0
   0
   0
   0
- 11
 + 2
   0
 + 1
   0
   0
   0
   0

...ja tulos näytti seuraavanlaiselta...

rivejä 15
rivillä 1 luku ei kuuluu joukkoon
./bash1.sh: line 9: [: too many arguments
rivillä 2 luku kuuluu joukkoon
rivillä 3 luku ei kuuluu joukkoon
rivillä 4 luku ei kuuluu joukkoon
rivillä 5 luku ei kuuluu joukkoon
rivillä 6 luku ei kuuluu joukkoon
rivillä 7 luku ei kuuluu joukkoon
./bash1.sh: line 9: [: too many arguments
rivillä 8 luku kuuluu joukkoon
./bash1.sh: line 9: [: too many arguments
rivillä 9 luku kuuluu joukkoon
rivillä 10 luku ei kuuluu joukkoon
./bash1.sh: line 9: [: too many arguments
rivillä 11 luku kuuluu joukkoon
rivillä 12 luku ei kuuluu joukkoon
rivillä 13 luku ei kuuluu joukkoon
rivillä 14 luku ei kuuluu joukkoon
rivillä 15 luku ei kuuluu joukkoon

..eli scripti ei tunnistanut (?) että plus tai miinusmerkin jälkeen tulee välilyönti ennen numeroa.
Jokaisella rivillä siis 4 merkkiä jonka jälkeen tulee rivinvaihto.

"""..tässä välissä hurjaa Googlausta..  ;) """

...ja onnistuin löytämään allolevan koodinpätkän jolla homma ratkesi  :D

sed -e 's/[\t ]//g;/^$/d'

...eli tuo poistaa välilyönnit.

Loppu onkin sitten vain pientä modausta, jossa echo't muutetaan arvoiksi joita vertaillaan.
Se toimii sittenkin !!!

-tjka-