Ubuntu Suomen keskustelualueet
Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: tjka - 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-
-
Helpoin varmaan tehdä Pythonilla, voit itse vaihtaa tiedostonnimet, ehdot ja tulostuksen oikeanlaiseksi:
#!/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
-
jotain tämmöistä
sed -n 1p tiedosto
nappaa ensimmäisen rivin jne.
if [ "$jotain" -gt 5 ] ; then
jotain
fi
tarkistaa onko luku suurempi kuin 5. -lt saat pienemmät kuin 5 jne
-
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-
-
Kyllä minusta näyttäisi toi snifin ehdotus toimivan niissäkin tapauksissa. Tosin en testannut, mutta algoritmi näyttäisi ottavan nekin huomioon.
-
Minä tekisin Pythonilla pikemmin näin:
#!/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:
./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:
#!/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.
-
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-
-
Mutta kuinka (en osaa yhtään Pythonia) saan kirjoitettua tulokset johonkin uuteen tiedostoon?
Avaamalla toinen tiedosto kirjoitusta varten.
Tosin jos haluat vain:
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.
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).
-
#!/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.
-
Print-käskyllä tulostamasi rivit Python-ohjelmassa voit uudelleenohjata komentoriviltä tiedostoon:
python testaus.py >tiedosto.txt
Toinen mahdollisuus on avata tiedosto Python-ohjelmassa kirjoittamista varten, ja kerätä tuloste siihen, jotakuinkin näin:
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.
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:
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)
-
Print-käskyllä tulostamasi rivit Python-ohjelmassa voit uudelleenohjata komentoriviltä tiedostoon:
python testaus.py >tiedosto.txt
Tuo on poistumassa oleva piirre.
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.
-
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-