Bash szkript kérdés

Sziasztok!

A következő a problémám. Van egy text fájlom, amit fel kéne vinnem egy MySQL adatbázisba. A mezőket space választja el egymástól. A gond azonban az, hogy az utolsó mezőben (a mellékelt példában az IP cím után) vannak további space karakterek.
Hogyan lehetne megoldani, hogy azok egy mezőbe kerüljenek be?
Egy ilyen fájl itt található.

Előre is köszi a segítséget.

Hozzászólások

sed-del próbáltam, de eddig csak addig jutottam el, hogy minden space-t átalakított...

Ha tudod azt, hogy hány mező van, akkor tudsz rá regex-et írni:
's/^( ... ) (...) (...)$/"\1"..../'
--
hup.user.js

nem bash, de...

awk 'BEGIN {ORS=" "} {for (i=6; i<=NF; i++) {print $i} print "\n"}' fájlnév

----------------------------
"Még jó, hogy nem szeretem a finomfőzeléket. Mert ha szeretném, meg kellene ennem. Pedig nem szeretem."

Bocs, azt hiszem, rosszul fogalmaztam meg, mit szeretnék.

Vagy egy ilyen sorom:

PsB:7517 V00C1A175] 9ddf0f39d8aab83684281716f1ea1f08 "(FL)_dirQS" "72.82.235.233" CVAR #9001 (AGP_Interface.AAGUIController AutoLoad User.ini = (MENUCLASSNAME=)

És ilyenné szeretném alakítani:

PsB:7517;V00C1A175];9ddf0f39d8aab83684281716f1ea1f08;"(FL)_dirQS";"72.82.235.233";CVAR #9001 (AGP_Interface.AAGUIController AutoLoad User.ini = (MENUCLASSNAME=)

de ha szigorúan hűek akarunk maradni a téma címéhez, akkor a bash script pl.:

#!/usr/bin/bash
while read -a tomb
do
for ((i=0;i<=`printf ${#tomb[*]}`;i++))
do
if (( i<6 ))
then
printf ${tomb[i]},
else
printf ${tomb[i]}" "
fi
done
printf \\n
done

az awk-s verzióm is mehet ciklussal:

awk '{for (i=1; i<=6; i++) {sub(" ",";")} {print $0}}' fajlnev

----------------------------
"Még jó, hogy nem szeretem a finomfőzeléket. Mert ha szeretném, meg kellene ennem. Pedig nem szeretem."

Helios megoldásával tökletesen működik. Panther, a doksit áttanulmányozom.
Köszönöm nektek!

Tiszteletem Mindenkinek!
Nem akartam új topicot nyitni,ezért ide írnék:

Azt hogyan lehet megoldani ,hogy egy általam kiválasztott felhasználó összes rendszerben eltöltött idejét kilistázzam?A last segítségével.Egyenként kilistázza,de összekéne adni.Összes idő kellene.
Lehetne időt is adni,hogy mettől meddig nézze.Ezt hogy lehet megcsinálni?

Ebben kérnék segítséget.
Előre is köszönöm!

Erre a célra AWK-ban vagy Perlben írnék egy egysoros szkriptet. Ha egyiket se használtad még, akkor javaslom az AWK-t (azon belül a GAWK-t), mert azt gyorsabban meg lehet tanulni, akár a man page alapján is. 1 óra alatt az AWK megtanulható, és még kb. 20 perc megírni a kívánt szkriptet, várható szkriptméret 300 bájt alatt.

(off)Hmmm... sikerült egy éles szerveren elengedni, format c: rulez. :-D (/off)

Lefuttattam, nekem megy a user nevét írhattad el:


hron@neuronhill:~$ last -R hron | grep -v 'still logged in' |  perl -e '$sum=0; while (<>) { s/^.*\((..):(..)\)/$sum+=$1*60+$2/e; } print "$sum\n";'
10102
hron@neuronhill:~$ 

Nekem is megy, bisztos tegnap valamit elnéztem,már fárad tvoltam :D

Perl nélkül szeretném megoldani,mivel perl nem értek és tudni is szeretném mi mit csinál.Sajnos még most ismerkedek a linux/unix-al ,s ne msok tapasztalatom van még.
Awk -val gondoltam.Biztos hogy bonyolultabb,de minden tapasztalat jól jön,csak hát így kcisit nehéz.
úgy kellene,hogy eyg script legyen,és ha elindítom akkor kéri be az user nevét,akit lekérdezzünk.
Read parancs segítségével olvastatok be,igaz?
(bújom az orlandó unix iskolát + script doksik) :D

Köszi!

Egy: arra van az előnézet gomb, hogy átfusd a szöveget. És gépelj lassaban.

Kettő: Ha nem akarod magad szétszivatni egy bonyibb problémával, ismerkedj meg a perl-lel, nem az ördögtől való, hidd el. Ajánlom Laura Lemay Perl mesteri szinten 21 nap alatt c. könyvet.

Próbálkozás a megoldásra awk-val:
#!/bin/bash
last |awk -F"(" '/gabo/ {print $2}'|awk -F")" '{print $1}'|awk -F: 'BEGIN
{ora=0; perc=0} {ora = ora + $1; perc = perc + $2} END {print "ora:"ora" perc:"perc }'

Futtatásnál ezt írja:
awk: line 1: syntax error at or near end of line

Már annyira nézem,hogy kigúvas a szemem,de ne mlátok hibát.
Hol lehet a hiba szerintetek?

set -x? Ezt miért gondoltad?nem értem...
Rosszabb lett:
+ . idok.sh
++ set -x
++ last
++ awk '-F(' '/fejer/ {print $2}'
++ awk '-F)' '{print $1}'
++ awk -F: 'BEGIN
{ora=0; perc=0} {ora = ora + $1; perc = perc + $2} END {print "ora:"ora" perc:"perc }'
awk: line 1: syntax error at or near end of line

Szia!
Ezt már nem hiszem el... :(
Javítottam,ahogy tanácsoltad,de ugyanazokat a hibákat dobja ki,viszont kiírja a megolást is.
Tehát a hibák megvannak,de a megoldást is írja.
Hogy kéen eltüntetni a hibákat?
Set -x mit jelent pontosan?Kerestem,de ne mtalálom sehol,manban nincs benne.

Ha már egyszer indítasz egy awk-t (nyilván ez lesz a legnagyobb overhead), akkor a többit teljesen felesleges. Gyorsabban fut, ha nem sok parancsból van összepájpolva. Viccesnek tartom az ilyeneket:

cat fájl | grep 'alma' | awk '{print $2}'

Értelmesebb volna így:

awk '/alma/ {print $2}' fájl

Tudom, kényelmetlenebb awk-ban programozni, mint összepájpolni egy ilyen izét, de ha a végrehajtási idő számít, akkor praktikusabb. Én szeretem a hatékony megoldásokat :)

hatékonyság XOR awk. Régen sokat awk-ztam, mert lényegében egy programozási nyelv, a többi eszközzel meg túl bonyolult volt. Ma meg azokkal kényelmesebb. Nem szeretem az awk-t :)

A példa meg a shell eszközeiről szól, mindegyik egy-egy részfeladatot old meg :D De ha zavar, lecserélem neked az awk-t printf-re :)

Nem kell, ne tedd. Bár elég érdekes kérdés, hogy meddig shell és honnan más. Vajon az ed és a sed még shell, de az awk és a perl már nem? Végül is mindegy. A lényeg, hogy ha lehet, akkor érdemes csökkenteni a pájpolt parancsok számát, ezzel gyorsul a futás, mivel itt általában a programok indítása és leállása több idő, mint maga a munka. (Biztos vagyok benne, hogy ez neked nem újdonság, csak az archívum miatt)

Sok megoldás van, itt van egy:
használat: script_neve feldolgozando_fajl hany_oszlopot_gyartunk
A scriptben 2 változót be lehet állítani: mit cserélni (what_to_replace) mire (to_what_to_replace).

#!/bin/bash
#settings start
what_to_replace=" "
to_what_to_replace=";"
# settings end
input_file=$1
loop_count=$2
read_content=`cat "$1"`
for((i=0;$i<$loop_count;i=$(($i+1))));
do
read_content=`echo $read_content | sed s/"$what_to_replace"/"$to_what_to_replace"/1`
done
echo $read_content"$to_what_to_replace"

--
Coding for fun. ;)

Kínszenvedések árán átírtam/tuk a felhsznált idos progit,bekéri az user nevét.
#!/bin/bash
echo "A program kiírja,hogy az adott felhasználó mennyi időt töltött a
rendszerben összesen."
echo " Add meg a felhasználó nevét"
read x
last|awk -F"(" ' /'$x'/ {print $2}'|awk -F")" '{print $1}'|awk -F: 'BEGIN{perc=0} {perc = $1*60 $2} END {print " '$x' felhasználói ideje:" perc}'

Hogy lehet azt megadni,hogy egy idQ intervallumban , pl: mondjuk 2007.01.02-2007.03.29 intervallumban írja ki a felhasználo összes rendszerben töltött idejét?
?

Nézd, a probléma ott van, hogy a 'last' igen limitált képességekkel rendelkezik; például ahol most nézem, ott nem lehet neki megadni, hogy pl. az bejelentkezés idejét feldolgozható formátumban közölje.
Három út marad:
1) a C-ben hekkelős,
2) a Perl/Python/whatewer-bindinges szebb megoldás, de mondjuk ezeket külön kell megszerezni rossz esetben, ld. python-utmp;
3) vagy az, hogy a last kimenetéhez hozzágányolsz egy awk kódot, tele olyan feltételekkel, amit már akkor nem fogsz átlátni, amikor írod.

én a 2-eset csinálnám

Értem.És a grep szűrővel?
Tuti,hogy egyszerűbb perl/pythonban,csak ezt nem tanuljuk,és azért kínlódnék ezekkel .
Esetleg nem tudnád leírni,hogy perlben hogy kellene megadni ezt za időintervallum közti keresést?


#!/bin/bash

echo -n "User: " && read user
echo -n "From (YYYY-MM-DD): " && read from
echo -n "Until (YYYY-MM-DD): " && read until

from=$(date -d "$from" +%s)
until=$(date -d "$until +1 day 0:0:0" +%s)

ac -dayz "$user" | sed 1d |
(
        sum=0
        while read line
        do
           D=$(date +%s -d "$(echo "$line" | cut -f1)")
           if [ "$D" -ge "$from" ] && [ "$D" -le "$until" ]
           then
                U=$(echo "$line" | cut -f2- | sed 's/^\s*total\s*//')
                sum=$(echo "$sum+$U" | bc)
           fi
        done
        secs=$(echo "$sum*3600/1" | bc )
        echo $((secs/3600)):$((secs%3600/60)):$((secs%60))
)

Üdv!

Bash-ban szeretnén összehasonlítani két változó értékét, így:

if [ $a -gt $b  ]
then
echo a nagyobb
fi

Az lenne a problémám, hogy a változókban tizedestörtek vannak és ezt sem ponttal, sem vesszővel elválasztva nem fogadja el, mondván

integer expression expected

. Meg lehet ezt valahogy csinálni?

Petya

Sziasztok!
Segítséget szeretnék kérni egy feladat megoldásához. Eddig próbálkoztam megoldani, de sajnos nem sikerült, így most végső elkeseredettségemben hozzátok fordulok. A feladat a következő:
"irjunk egy expr2.sh parancsot amely az az expr parancs kepessegeit egesziti ki
sqrt, egy hatvanyozasi kepesseggel"

Holnap reggel kell leadni. Előre is ködöznöm a segítséget!

"Eddig próbálkoztam megoldani, de sajnos nem sikerült, ..."
Rendben. Akkor az lenne a legcélszerűbb, ha idemásolnád a te egyelőre nem működő változatodat, és azt alakítanánk. Illetve azt is, hogy milyen formában tervezed a kifejezésben megadni a hatványozás műveletét.

"irjunk egy expr2.sh parancsot amely az az expr parancs kepessegeit egesziti ki sqrt, egy hatvanyozasi kepesseggel"
Az sqrt több nyelvben is a négyzetgyökvonás műveletét jelenti, a bash önmagában ilyet nem tud. A ** operátor segítségével hatványozni is csak egész típusú operandusok között lehet, és a kitevő sem lehet negatív.

stra: Őszintén megmondom, hogy nem nagyon értek (még) ehez, ezért nem hiszem, hogy a próbálkozásaim építőjellegűek lennének. Ha meg tudná valaki írni az egészet annak megköszönném. Sokat nem tudok adni, max egy nagyon ízletes Bocsi csokit :) Köszönöm!

(u.i.: Sikerült még szerezni pár nap haladékot)

Segítünk megírni. Hangsúly a segítésen. Neked is hozzá kellene tenni valamit, nem helyetted írjuk meg, az hosszú távon neked sem jó.

Elsőként azt kellene meghatározni, hogy mit is szeretnél, mert a kiírás a fenti formában nem egyértelmű. Gyökvonást (sqrt) vagy hatványozást? Elég-e az egész számokkal foglalkozni, vagy tört is lehet? Használható-e a hrgy84 által ajánlott bc vagy csak tisztán a bash? Egyáltalán mik a megengedett és tanult eszközök (grep, sed, awk, bc, perl, regexp)?

Szóval ezeket a kérdéseket válaszold meg légy szíves, ezek nélkül nem tudhatjuk, hogy merre indulhatunk, és nyugodtan másold ide az eddigi próbálkozás eredményét, akkor is, ha nem működik, szintaktikailag hibás.

Nem feladat, csak kíváncsi vagyok. Hogyan lehet kötőjellel kezdődő fájlneveket kezelni? Egy album volt ilyen formátumban. Kénytelen voltam mc-vel átnevezni, miután az mplayer nem játszotta le őket és az mv parancs sem működött.

stra: Őszintén megmondom, hogy nem nagyon értek (még) ehez, ezért nem hiszem, hogy a próbálkozásaim építőjellegűek lennének. Ha meg tudná valaki írni az egészet annak megköszönném. Sokat nem tudok adni, max egy nagyon ízletes Bocsi csokit :) Köszönöm!

(u.i.: Sikerült még szerezni pár nap haladékot)

Amíg nem kapunk érdemi válaszokat a fent feltett kérdésekre, addig nem nagyon lesz ötlet a már elhangzottakon kívül. A feladatkiírást pedig kizárólag te ismered. Azt sem tudjuk biztosan és pontosan, hogy mit és mivel kell csinálni.

Legalább azt írd le, hogy hogyan tervezed megoldani, a konkrét parancsokra pedig adunk javaslatokat. Legalább egy nagyon kis önálló kezdeményt, tervet, légy szíves...

"nem hiszem, hogy a próbálkozásaim építőjellegűek lennének."
Nem annyira az építő jellegen vagy a működőképességen, hanem az önálló próbálkozáson van a hangsúly.

A feladat leírás:
"irjunk egy expr2.sh parancsot amely az az expr parancs kepessegeit egesziti ki
sqrt, egy hatvanyozasi kepesseggel"

Ennyit tudok én is:(

"Ennyit tudok én is:("
De az elmúlt egy hét alatt a feltett kérdések nyomán csak kiderült (utánajártál) az, hogy négyzetgyököt kell vonni (sqrt) vagy hatványozni kell, illetve milyen alap és kitevő jöhet szóba, milyen külső programok használhatóak - ha használhatóak egyáltalán a bash-en kívül, milyen szintaktikával kell megadni a (még mindig kérdéses) műveletet.

Ezek a kérdések azért vannak, mert alapjaiban határozzák meg a használható eszközöket, illetve ugyanez fordítva is érvényes. Ha ezekre nem tudsz határozottan válaszolni, akkor a feladat pontosításra szorul, és ezt csak te tudod megtenni. Egy nem egyértelmű kiírásból mi nem tudjuk kitalálni, hogy tőled mit kérnek. Egy iskolai feladat esetén általában nem engednek a tanultakon kívül mást használni. Ha mégis, illetve gyökvonásról van szó, akkor pedig ott a hrgy84 által említett bc.

Megjegyzés: a feladat szövegezése így másodszorra leírva is erősen magyartalan és értelmetlen, ahogy az eredeti is az (14.): "egesziti ki ... egy hatvanyozasi kepesseggel", "az az expr parancs kepessegeit egesziti ki sqrt, egy hatvanyozasi kepesseggel". Hopp, itt van a wgetes és a gráfos feladat is. :)

Pontosan nem tudtam megérdeklődni, mert külföldön van az illetékes, de gondolom hatványozni kellene. Kb a legegyszerűbb megoldás kellene, még kb csak "alapnak" számító kis pici programokat írtunk (listázzuk ki könyvtár tartalmát képernyőre pl), még nem írtunk olyan scriptet ami külső programot használna.

"még nem írtunk olyan scriptet ami külső programot használna."
Ez akkor elég korlátozott képességű lesz, de legyen így. Ha ebben a formában megfelel, akkor ez lesz a script működése:


  ha a script elsőtől kezdődő pozícionális paraméterei tartalmaznak "**"-ot
  akkor
    kiíratjuk a shellel kiértékeltve
  különben
    meghívjuk vele az expr parancsot a hibaüzenetet elnyomva, a kimenetet változóba téve
    ha a visszatérési értéke nagyobb vagy egyenlő kettővel
    akkor
      hibaüzenet kiírása
    különben
      kiírjuk a változó értékét
    elágazás vége
  elágazás vége

Neked már csak a bash parancsait, operátorait kell behelyettesítened.
Ha nem találod a megfelelőt, segít a man bash, itt keresd:
a script elsőtől kezdődő pozícionális paraméterei külön vagy egyben kezelve: Special Parameters
shellel kiértékeltetés: Special Parameters
logikai kifejezés vizsgálata: Compound Commands
parancs kimenete változóba: Command Substitution

Azt hiszem, így már nem lesz túl nehéz, negyed óra alatt át lehet írni.

Próbálgattam csinálni a feladatot...eddig jutottam:
#!/bin/sh
if [ $# -ne 3 ]
then
echo "Hiba"
else
echo $@ > tmp.file
#echo $0 > tmp.file
awk '{
print $1;
print $2;
print $3;
#if($2=="sqrt") { print sqrt($1,$3);}
# if($2=="pow") { print pow($1,$3);}
#if($2!="sqrt"&&$2!="pow"){ print `expr $1 $2 $3`;}
}' tmp.file
# rm tmp.file;
fi

Futtatás:./expr2.sh1pow2
Már cska akirás hiányzik belőle; if-ekkel gondolnám megcsinálni,csak nem igazán tudom,hogy hogy.
Hogyan módosítanátok ezt, hogy kiírja az eredményt? Hogy kell azt megcsinálni?

Előre is köszi a help-et.