Halihóóó Emberek!
Egész számot, amely byte - okat jelent, szeretnék 1024 - el osztani, hogy G, M vagy kbyte - okat kapjak. Az eredmény két tizedesjegyig kellene. Külső program (pl. bc) vagy más nyelven írt script beágyazása nélkül megoldható - e ez tisztán bash módszerrel?
- 11828 megtekintés
Hozzászólások
Nem lehetséges, amennyire tudom.
Ha shell-csere megoldható, akkor javaslom a zsh-t (ld. itt, "Floating Point Math" rész).
- A hozzászóláshoz be kell jelentkezni
Ugye nem matekot tanítasz? ;)
- A hozzászóláshoz be kell jelentkezni
De. De látom már, mi a trükk. Párszor már használtam is pedig. Hogy hogy nem jutott eszembe... ne firtassuk ;)
- A hozzászóláshoz be kell jelentkezni
Tudom, mert valahol már említetted... csak gondoltam, szórakozok egy kicsit. ;)
(bár ha megnézed, én viszont a bash-t kellene, hogy ismerjem legalább annyira, mint neked a szorzás/osztást, aztán a printf mégis behúzott a csőbe, mert nem figyeltem oda)
- A hozzászóláshoz be kell jelentkezni
Valahogy nagyon arra járt az agyam, hogy bash-ban nincs tizedestört, zsh-ban meg van. Na, mindegy.
- A hozzászóláshoz be kell jelentkezni
Mi a trükk? Nekem így hirtelen okénak tűnik.
--
Debian - The "What?!" starts not!
http://nyizsa.blogspot.com
- A hozzászóláshoz be kell jelentkezni
??? Okénak tűnik az a megjegyzés, hogy nem lehet megoldani shell-eszközökkel, holott alant azért kiderült, hogy de, lehet? A shell ugyanis jelenleg integer aritmetikát kezel, és mind egész osztás, mind maradékképzés funciója van.
- A hozzászóláshoz be kell jelentkezni
Ahogy Zahy is írta. Lényegében hogy oly módon lehet megoldani ("kerülő" úton), hogy a százszorosával végzem a műveleteket, utána pedig maradékos osztással megkapom a kívánt eredményt. Erre gondoltam, hogy ez nem jutott eszembe, pedig már én is használtam párszor (nem bash-nál).
- A hozzászóláshoz be kell jelentkezni
Ja, az oké. Az első pár hozzászólásból úgy jött le valamiért, hogy a zsh-s megoldás valamiért hibás, pedig teljesen jónak tűnt. De akkor az is.
--
Debian - The "What?!" starts not!
http://nyizsa.blogspot.com
- A hozzászóláshoz be kell jelentkezni
Esetleg, bar ez azert nem teljesen igaz, kiindulasnak jo lehet.
x=2;y=3;r=$((x/y)).$((100*x/y)); echo $r
- A hozzászóláshoz be kell jelentkezni
Ezt azert finomitsd :-)
$ x=12;y=3;echo $((x/y)).$((100*x/y))
4.400
- A hozzászóláshoz be kell jelentkezni
Hu, vissza kellene ulnom az iskola padba :-)
x=12;y=3;r="$((x/y)).$((100*(x%y)/y))";echo $r
4.0
x=2;y=3;r="$((x/y)).$((100*(x%y)/y))";echo $r
0.66
- A hozzászóláshoz be kell jelentkezni
Ez már sokkal jobb, de nem elég pontos:
calc 23456789/1024
22907.0205078125
x=23456789;y=1024;r="$((x/y)).$((100*(x%y)/y))";echo $r
22907.2
Nekem is van egy megoldásom, modulo használata nélkül, de sajnos az is pont ugyanígy hibázik.
x=23456789;y=1024;r=$((x/y)).$((100*x/y-(x/y)*100)); echo $r
22907.2
Tipp: ha csak egy tizedesig számolunk így, akkor pontosabb az eredmény.
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
printf "%d.%02d" $((X/Y)).$((X%Y*100/Y))
(próbálom menteni a menthetetlent)
- A hozzászóláshoz be kell jelentkezni
Ez így frappáns, (bár pici korrekciót igényel):
printf "%d.%02d" $((X/Y)) $((X%Y*100/Y))
- A hozzászóláshoz be kell jelentkezni
Ja igen. Először így írtam, utána néztem, hogy honnan lesz tizedespont, és odaraktam. Persze a tizedespontot a formátumsztring fogja adni...
- A hozzászóláshoz be kell jelentkezni
nem jo ha a 0 < maradek < 10. pl 101/100 <> 1.1
- A hozzászóláshoz be kell jelentkezni
Teljesen jogos. A megoldasom helytelen!
- A hozzászóláshoz be kell jelentkezni
x=1;y=100;r="$((x/y)).$((100*(x%y)/y))";echo $r
0.1
nem kéne valami if-szerűség?
- A hozzászóláshoz be kell jelentkezni
Megelőztek. :-(
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
printf "%.2f\n", $(($bytes*100/1024))
Ez így nem jó?
- A hozzászóláshoz be kell jelentkezni
Mi is az, hogy "tisztán bash"?
A bash-nak lényegi része, hogy bc-t, vagy awk-t vagy cut-ot ... stb hívogatunk. A grep-ről nem is beszélve. Az sem része a bash-nak.
Ha elmondod mi a feladat, lehet hogy más utat is találunk, és nem kell számoltatni.
Pl: ha file méreteket akarsz megjeleníteni, akkor az ls -h ugyanígy mutatja, illetve a du -sh is. Csak példa volt, de lehet máshol is van ilyen megoldás. Ne számolj ha nem muszáj. ;)
---
"A megoldásra kell koncentrálni nem a problémára."
- A hozzászóláshoz be kell jelentkezni
A bash-nek nem része egyik említett program sem.
Valamennyi használata plusz processz indítást jelent, aminek elég nagy az erőforrásigénye.
De én továbbra is (immár kipróbáltan) kitartok amellett, hogy az osztandót fel kell szorozni 100-zal, elvégezni az osztást, észben tartani, hogy az eredménye épp százszorosa a ténylegesnek és amikor ki kell írni, akkor printf, formátumként "%.2f", értékként meg $(($eredmeny/100)) és probléma letudva.
(kerekítés nem erőssége, de itt asszem, nincs jelentősége)
- A hozzászóláshoz be kell jelentkezni
nálam:
bytes=100;printf "%.2f\n" $(($bytes*100/1024))
9,00
ugyhogy valami gond van ezzel. (a vesszo szerintem nem kell) -- nem tudtam hogy printf is van a bash-ban. mindenesetre ha mar van akkor en is eloallok egy lehetoseggel (ez egy szkript vagy mi)
x=$1
y=$2
printf "%d" $(($x/$y))
x=$(($x%$y))
x=$((100*$x))
printf ".%02d\n" $(($x/$y))
- A hozzászóláshoz be kell jelentkezni
Sajnos igazad van. Én is csak olvastam, hogy van %f a printf-ben, nem próbáltam ki. Viszont ahol olvastam, ott hitelesnek tűnt a dolog. :)
Illetve pontosítok: figyelmetlenül próbáltam ki, nem tűnt fel, hogy olyannal osztottam, ahol eleve 0 a tizedesvessző utáni rész... :)
Hát így macerás és nem is igazán értem, hogy mi értelme lebegőpontos formátumot belerakni, ha nem tud számolni vele. :(
- A hozzászóláshoz be kell jelentkezni
Értem én, hogy minden segédprogi plusz process.
Azt is értem, hogy bizonyos környezetekben ez "drága".
De akkor eleve hagyjuk a bash-t. Legyen tisztán bc. Vagy awk. vagy perl. bash nélkül.
Visszacsatolás eredeti felvetésemhez: kéne ismerni a pontos feladatot.
Lehet hogy az eredeti feladat megoldásában hatékonyabban tud segíteni a közösség, mint egy akadémiai gondolatkísérlet levezetésében.
(Hacsak az eredeti cél, nem maga az akadémiai gondolatkísérlet :D )
---
"A megoldásra kell koncentrálni nem a problémára."
- A hozzászóláshoz be kell jelentkezni
Nem akarok fogatlan provokátor lenni, de linuxon a bash szinte biztos, hogy ott van, a bc meg az awk pedig szinte biztos, hogy vagy igen vagy nem - hogy processz keletkezne-e belőlük, az csak a 2. stáció.
Ahol ez számít, ott nem csak akadémiailag.
- A hozzászóláshoz be kell jelentkezni
Szervusz!
Pontosan ezért szeretném elkerülni külső program használatát. Pl. nálam a bc alapjáraton nincs telepítve. Sokkal hordozhatóbb a script, ha egy egyszerű osztás miatt (amit érzésre meg kell tudni oldani külső program nélkül is) nem követeljük meg egy másik program telepítését.
- A hozzászóláshoz be kell jelentkezni
x=23456789; y=1024
r0=$((100*$x/$y)); len=${#r0}
int=${r0:0:$(($len-2))}; frac=${r0:$((len-2)):2}
r=${int:-0}.$frac; echo $r
- A hozzászóláshoz be kell jelentkezni
Köszi, ez használhatónak tűnik! Először meg kell nézni, hogy az osztandó nagyobb - e, mint 1024 * 1024 *1024, vagy 1024 * 1024 vagy 1024, ennek függvényében az osztó 1024 * 1024 * 1024 vagy 1024 * 1024 vagy 1024. Ekkor a módszered szerint jöhet az osztás, a prefixum pedig az osztóval összhangban G, M vagy k.
- A hozzászóláshoz be kell jelentkezni
Azért nem mellesleg érdekes lehet a feladat is, mert a fájl, könyvtár stb. méretek kiírásához sok esetben elég, ha az adott utility megfelelő kapcsolóját (man-ban általában human readable v. hasonló címszó alatt találod) használod.
- A hozzászóláshoz be kell jelentkezni
A fentiek konkúziójaként - erőforrás, processz stb. - általában a stat() függvényt használom. Ezzel szemben bash-t nem indítok, mert erőforrásigényes. :))) Ez azért napi 55.000.000 processz mellett nem mindegy.
- A hozzászóláshoz be kell jelentkezni
1024-gyel
t
- A hozzászóláshoz be kell jelentkezni
Valami ilyen őrület?
x=654876546;
echo $(( $x>>10)).$((($x & 1023) * 100>>10))
- A hozzászóláshoz be kell jelentkezni
Beszarás!
- A hozzászóláshoz be kell jelentkezni
Itt is kellene amugy valami elagazas, mert itt is megvan az a halmaz (10-102 kozott) ahol teves eredmenyt produkal. A megoldas viszont tetszetos ezt leszamitva :)
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..
- A hozzászóláshoz be kell jelentkezni
[Feliratkozás]
- A hozzászóláshoz be kell jelentkezni
Idegesített engem ez a probléma, aztán kókányoltam egy ilyet fpc-vel:
http://sourceforge.net/projects/sh-math/files/sh-math/sh_math-1.0/
Gyakorlatilag csak paraméterelemzés -> számolás -> kiírás.
Előbb utóbb átírom c-re is :D
Használata:
sm_div 654654654 1024
vagy:
sm_rdiv 654654 1024 | sm_tostring -p
-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba
- A hozzászóláshoz be kell jelentkezni
Én csak azt nem értem, hogy ez mennyivel jobb, mint az awk.
- A hozzászóláshoz be kell jelentkezni
Vagy a bc, a calc, ...
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
A linknek álcázott valamit (semmit?) kifejtenéd részletesebben?
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
Hm, gondatlan voltam. Van FreeBSD alatt egy "e" nevű jószág, aminek a port-Makefile-jában volt egy link. Mint utóbb kiderült, a vakvilágba vezet. Jobb híján ezt ajánlom nézegetni: ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/e-0.02718.tar.gz
- A hozzászóláshoz be kell jelentkezni
Óriási...
- A hozzászóláshoz be kell jelentkezni
Ja, a forraskod doksival 13-14K, egy db .c fajl, a binaris libc es libm fuggoseggel 10K alatt van. Es tudja azt, ami kell atlag napi hasznalatban. En ezert szeretem :-)
- A hozzászóláshoz be kell jelentkezni
De ilyet azért nem tud:
tarolo:/usr/bin$ sm_tosys 16 178768768
AA7CB80
tarolo:/usr/bin$ sm_fromsys 16 AA7CB80
178768768
tarolo:/usr/bin$ sm_tosys 36 178768768
2YFMV4
tarolo:/usr/bin$ sm_fromsys 36 2YFMV4
178768768
-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba
- A hozzászóláshoz be kell jelentkezni
Ezzel egyetértek, bár ha az "e" tudásánál bonyolultabb kell, akkor én előveszem a bc-t.
Egyébként ha a bash nem lenne olyan buta, akkor pl. a számrendszerek közti váltást simán meg lehetne ejteni úgy, ahogy a Korn-shell (*) pár évtizede már tudja:
$ typeset -i16 i=8#33 ; echo $i
16#1b
$
Azaz az i változóra beállítom, hogy 16-os számrendszerben tessen kezelni, majd értékül adom neki a 8-as számrendszerben értelmezett 33-t (ami ugye 27). A kiíratás pedig az adott változóra érvényes számrendszerben jelenik meg (amit persze jelez is). Vagy ha utólag jövök rá hogy konvertálni akarok, akkor csak átállítom az alapszámot, és kész.
Sajnos a bash nem ismeri a typeset -i esetén a számrendszer alapszámának megadását, ő csak 10-esben hajlandó megjeleníteni, de integer tipusú változónál a bash is hajlandó elfogadni a spéci formában levő bemenetet. Azaz ha elég a valamiből 10-esbe konverzió, akkor bash alatt is lehet így:
$ typeset -i i=8#33 ; echo $i
27
(Amúgy "bash" alatt "typeset"-ként kevéssé szokták ismerni, ott valamiért "declare"-nek szeretik hívni az adott parancsot - viszont mivel mind a kettőt megeszi, én jobb szeretem a hordozhatóbb formát használni.)
(*) ami a ksh93-s nevű verziójában amúgy float változótipust is kezel typeset -f v formában.
- A hozzászóláshoz be kell jelentkezni
Ezzel szemben a line editing már a használhatatlanságig fejlett. :(
- A hozzászóláshoz be kell jelentkezni
Végtére is: nem a parancsértelmező "dolga" a számolgatás. Futtatni tudjon, elágazást/ciklust szervezzen, stdin-t, stdout-ot kezeljen, számolóprogram meg van dögivel, úgyhogy "no problem" :)
-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba
- A hozzászóláshoz be kell jelentkezni
Fene tudja. Ha programot kell indítania önálló process-ben, az sok idő. Éppen ezért hatékonynak tartom, ha külső program indítása nélkül meg lehet a shellben oldani dolgokat.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
+1
Ha már ciklust tud szervezni, legalább a ciklusszámlálót számolja ki az ujjocskáin! :)
- A hozzászóláshoz be kell jelentkezni
Ciklusszervezesnel megis honnan lesz ciklusszamlalo leptetes? Szerintem eleg kevesen vannak ma mar, akik leirnak ilyeneket:
a=1
while [ "$a" -le 1000000 ] ; do
BLABLA
a=`expr "$a" + 1`
done
pedig itt pont az tortent, hogy az original Bourne-shell-nek nem volt aritmetikai muvelete, ezert aztan kenytelen volt az ember ilyen nyakatekert (es mint elottem mar jeleztek - iszonyat eroforraspazarlo modon) leptetni egy rohadt ciklusvaltozot.
Anno az eredeti Bourne-shellhez kepest a C-shell nagyon sok extra funkciot hozott be (iszonyat szarul implementalva, de mindegy), tobbseguk az interaktiv hasznalatot volt hivatott kenyelmesebbe tenni (history pl.), de bizony az ertekadashoz bevezetett @ parancs pontosan behozta az aritmetikai muveletvegzo kepesseget. Azt, hogy ez hasznos, mi sem bizonyitja jobban, mint az, hogy azota ez a lehetoseg minden shellben azota is letezik - legfeljebb nem a csh-ban bevezetett szintaxissal, lasd: (( a = a + 1 )) vagy a=$(( $a + 1 )) vagy a mar fent emlitett typeset -i a ; a=a+1 (jobb shellekben ezt is lehet ugy irni, hogy integer a, amugy)
- A hozzászóláshoz be kell jelentkezni
Sőt ((a++)).
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A kiértékelés is új processt futtat:
while [ "$a" -le 1000000 ] ...
ennyit tesz:
while `test "$a" -le 1000000`
-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba
- A hozzászóláshoz be kell jelentkezni
Az a test nem a (/usr)/bin/test, hanem beépített shell rutin.
A külső test csak abszolút hivatkozó szkriptekhez, és helytakarékosra fordított shellekhez maradt meg.
- A hozzászóláshoz be kell jelentkezni
Hogyha a backtick nem lenne ott, akkor meg jo is lenne. Es amugy nem, a while test vagy while [ forma esetén nem lesz újabb proceszed. Persze ha odateszed a hanyatt-aposztrófot, akkor már lesz új processz. Igaz, az úgy szemantikailag hibás forma :-)
- A hozzászóláshoz be kell jelentkezni
Ezzel - az általam egyébként elfogadható - érvvel picit szembemegy a bashnek azon törekvése, hogy ezekbe a kategóriákba nem sorolható fícsöröket viszont agyontámogasson; amivel sikerült már odáig eljutni, hogy ember legyen a talpán, aki megmondja, hogy egy adott disztrib adott bash verziójának futása közben egy adott parancsnév után tabot nyomva mi fog történni.
- A hozzászóláshoz be kell jelentkezni
perfekt :)
-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba
- A hozzászóláshoz be kell jelentkezni
echo 65535/1024 | bc -l
Én csak ezt a lehetséges módszert láttam eddig. Azon lepődtem meg, hogy a Linux kernel fordításához is kell a bc.
Egyéb praktikus lehetőség: perl vagy python szkript.
- A hozzászóláshoz be kell jelentkezni
Vagy awk.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Tetszőleges tizedesszámra (t):
t=${t:=2}
h=$((x/y)); echo -n $h.
while (( t-- ))
do
x=10*$((x-h*y))
h=$((x/y))
echo -n $h
done
echo
Kerekíthetünk is, ha az utolsó osztást kivesszük a ciklusból.
- A hozzászóláshoz be kell jelentkezni
Anélkül, hogy végiggondoltam volna, szerintem nem jó. Az aktuális könyvtárba tudnék olyan nevű file-t tenni, amitől elromlik.
Az x=10*$((x-h*y)) kifejezésben az első csillag shell globbing. Vagy backslash kell a csillag elé, vagy idézőjelezni kellene, megfelelő helyekre az aposztrof is jó, legvégső esetben az x értéke akár ki is számolható. Mert így az x értéke egy string, amely ugyan kiszámolódik a következő helyettesítéskor, de kiszámolódhatna rögtön az x értékadásakor is.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Hmm, ha jól értelmezem, akkor ez attól függ, hogy az integer attribútummal rendelkezik-e az x változó. Az én bash verzióm úgy tűnik, az aritmetikai kifejezés miatt az egész értékadást aritmetikainak értékeli. (A x=10*x valóban hibás, kivéve, ha deklaráltuk a változót: declare -i x, ekkor elvileg a $(()) sem kell.)
De hogy ne legyen kérdéses:
x=$((10*(x-h*y)))
- A hozzászóláshoz be kell jelentkezni
Így van. Nézzük ezt a példát:
x=8; h=2; y=3
x=10*$((x-h*y))
echo $x
10*2
Ellenben:
x=8; h=2; y=3
: >10a2
x=10*$((x-h*y))
echo $x
10a2
Ráadásul hibát sem generál, ha a globbing szám nevű filenév, például 1035912.
Neked azért működött, mert a glob nem illeszkedett semmire, ilyenkor a bash a *-ot literálisként helyettesíti. A másik dolog, hogy az így kapott string - jelen példában 10*2 - a következő körben az aritmetikai kifejezésbe helyettesítődött, ahol egyben kiszámolódott. További szerencséd, hogy a szorzás magasabb precedenciájú az összeadásnál, így még el sem számolta magát. :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni