Hirdetés

2024. április 19., péntek

Gyorskeresés

Hozzászólások

(#51) Jester01 válasza ALI_G (#50) üzenetére


Jester01
veterán

Ciklusban olvasod soronként, és minden 24. után beiktatsz egy read-et.

Jester

(#52) ALI_G válasza Jester01 (#51) üzenetére


ALI_G
veterán

ez OK, de a head az mindig az állomány első X sorát írja ki. Szóval ha az első ciklus lefut, akkor a következőben megint csak az első 24-et írná ki.

(#53) Jester01 válasza ALI_G (#52) üzenetére


Jester01
veterán

Headet felejtsd el. Simán olvasd be egy shell ciklusban egyesével a sorokat (read) és írasd ki (echo).

Jester

(#54) ALI_G válasza Jester01 (#53) üzenetére


ALI_G
veterán

én itt keresgéltem a read-del kapcsban, de nem tudom hogy érted. Fájlból hogy olvassak be a read-del soronként? :F
A read-et csak úgy ismerem, hogy ENTER leütéséig olvassa a leütött karaktereket a Standard inputról. Ha átirányítom egy fájlba read > fájl, akkor beleírja. vagy vhogy így.
Te ezt hogy gondolod, mert én nemtom.

közben azért próbálkozom.

[Szerkesztve]

(#55) Jester01 válasza ALI_G (#54) üzenetére


Jester01
veterán

Igen, a read a standard inputról olvas, enterig. Viszont az átirányítással éppen a standard inputhoz rendelhetsz másik fájlleírót.
Csak éppen a másik irányba kell átirányítani: read < file :C
(Persze ciklusban kicsit másképp.)

Jester

(#56) ALI_G válasza Jester01 (#55) üzenetére


ALI_G
veterán

bocs, de nekem ez a retek eccerű script se fut le:
echo ''peldaprogi'' $(read < ize.txt)
természetesen előtte van a #! /bin/bash

(#57) Jester01 válasza ALI_G (#56) üzenetére


Jester01
veterán

Ez nem is. A read az változó(k)ba olvas. A te példád is beolvasott egy sort, csak aztán eldobta. Helyesen:
read sor < ize.txt
echo $sor

Jester

(#58) ALI_G válasza Jester01 (#57) üzenetére


ALI_G
veterán

igazad van, le is esett.
Viszont most olyan problémám van, hogy minden egyes alkalommal csak 1 sort olvas be a read:
#! /bin/bash
COUNT=0
while [ $COUNT -lt 2 ]
do
read sor < $1
echo $sor
COUNT=$(($COUNT+1))
done


azért 2-ig megy a count, mert kis fájlon tesztelem. Ha működni fog arra hogy kettessével irogassa Enterenként, akkor átírom 24-re.

(#59) Jester01 válasza ALI_G (#58) üzenetére


Jester01
veterán

Mert itt már a while-nak (illetve az azt futtató alshellnek) kell megadni az átirányítást.

while [ $COUNT -lt 2 ]
do
read sor
echo $sor
COUNT=$((COUNT+1))
done < $1

MOD: Illetve kezdők jobban szokták szeretni a cat $1 | while ... formát mert jobban átlátható. Viszont indít egy fölösleges cat processzt.

[Szerkesztve]

Jester

(#60) ALI_G válasza Jester01 (#59) üzenetére


ALI_G
veterán

Ez zsír. A fájl végét hogy vizsgálom? Azért kérdem, mert úgy képzeltem el, hogy

while !(fájl vége)
do
while [ $COUNT -lt 2 ]
do
read sor
echo $sor
COUNT=$((COUNT+1))
done < $1
read
done

[Szerkesztve]

(#61) Jester01 válasza ALI_G (#60) üzenetére


Jester01
veterán

Ez így nem lesz jó, mert a belsõ ciklus mindig újrakezdi a fájl olvasását az elejérõl.
Szóval mindenképpen az a while read sor kell kívülre. Belül meg simán csak számolod a sorokat, és 24 után egy if segítségével vársz egy entert és nullázod a számlálót. Még lesz vele egy kis gubanc, mégpedig az, hogy az entert váró read is a már átirányított fájlból akar majd olvasni. Szóval azt meg vissza kell irányítani a terminálra :U Ehhez célszerû elmenteni a ciklus elõtt az stdin fájlleíróját, és a belsõ readnek megadni. Olvasd el a man bash átirányításról szóló részét, különös tekintettel a fájlleirók másolására.

Jester

(#62) ALI_G válasza Jester01 (#61) üzenetére


ALI_G
veterán

atya-gatya...lehet kezdünk mélyre ásni. Ezt már csak holnap este tom megnézni. De amúgy nagyon köszi!

(#63) ALI_G


ALI_G
veterán

uh, kicsit sokáig voltam Pesten, tovább mint terveztem. Most jöttem, és van most is 1 kérdésem:
Ez mit jelent:?

IFS=$'\\\\n'

(#64) Jester01 válasza ALI_G (#63) üzenetére


Jester01
veterán

Ebben szerintem kicsit sok a backslash.
Az IFS egy shell beépített változó, ami a mezőhatárokat adja meg, pl. a read parancs esetén, illetve összefűzéseknél.

Jester

(#65) ALI_G válasza Jester01 (#64) üzenetére


ALI_G
veterán

nem mondom h teljesen értem, de innen szedtem: [link]

mod.: gáz van. Nemtok be SSH-zni suliba megnézni a bash manuálját, hogy lehet ezt megcsinálni: Ehhez célszerû elmenteni a ciklus elõtt az stdin fájlleíróját, és a belsõ readnek megadni.. Neten fent van magyarul?
most linuxot nincs kedvem letölteni (live), feltelepíteni meg végképp nem is tudnék hely hiányában.

[Szerkesztve]

(#66) ngabor2


ngabor2
nagyúr

van egy ilyen kis szkriptem:

#!/bin/bash
rm -rf mp3dir
stdir=`pwd`
koz=''_''
mkdir mp3dir
mpdir=$stdir/mp3dir
k=0;
find . | grep \.mp3$ | sort > mp3list.txt
i=`wc -l mp3list.txt | cut -d'' '' -f1`
for j in `seq -w $i `
do
mpfile=`cat mp3list.txt | head -n $j | tail -n 1;`
mp=`basename ''$mpfile''`
cp ''$mpfile'' $mpdir/''$j$koz$mp''
done;


működik rendesen (mp3-albumokat sorszámoz, és 1 kt-ba pakolja. egyes mp3-lejátszóknál jól jön), csak nem túl elegáns, hogy mindig létrehoz egy mp3list.txt állományt. meg lehet-e oldani, hogy ne egy file-on keresztül kelljen sorbapakolni a file-okat, hanem pl. egy változóba, vagy valami hasonló, memóriában helyet foglaló cuccban? vagy ha úgy macerás, akkor egy tmp-file-ba (tehát szabályosan kezelje a /tmp könyvtárat, véletlenszerű névvel)?

(#67) ALI_G válasza ngabor2 (#66) üzenetére


ALI_G
veterán

Na ezt most nem értem. Neked az a fájl nem kell a végén? Mert akkor elég ha átirányítod a null-ba, és semmi nyoma nem marad.

(#68) Jester01 válasza ngabor2 (#66) üzenetére


Jester01
veterán

Szerintem ezt embertelenül elbonyolítottad ;)
Ha fixen tudod hány számjeggyel szeretnél sorszámozni akkor ez kb. ennyi:

j=1
find . -name '*.mp3' | sort |
while read mpfile
do
cp ''$mpfile'' ...
j=$((j+1))
done

Jester

(#69) ngabor2 válasza Jester01 (#68) üzenetére


ngabor2
nagyúr

na ez az! köszi.

a szkript kb. 1 éve kezdődött, eddig 5 verziót élt meg, és közel 0 szkriptelési tudással kezdtem neki.

az eredeti ''probléma'' az is volt, hogy nem tudom, hány számjeggyel számozom a file-okat, de ez a legtöbb esetben 3. a seq -w is emiatt került bele, azelőtt egy 3-részes if-sorozat volt benne, de az annyira gányul nézett ki, hogy szörnyű :D

most is igaz, hogy a legegyszerűbb dologra nem gondoltam, pontosabban ezt a módszert nem ismertem.

(#70) Jester01 válasza ngabor2 (#69) üzenetére


Jester01
veterán

Akkor itt egy kis trükk, hogyan lehet ifek nélkül 0val azonos hosszra kitölteni számokat:

Inicializálás:

last=999
len=${#last}
zeroes=${last//[0-9]/0}

$i kipótlása:

tmp=''$zeroes$i''
padded=${tmp: -len}

MOD: az utolsó sorba a : után szóköz kell!

[Szerkesztve]

Jester

(#71) ngabor2 válasza Jester01 (#70) üzenetére


ngabor2
nagyúr

ehh, ez nekem már magas... lehet, hogy annak idején mégiscsak fel kellett volna vennem a progmatot a vegyészet mellé?

(#72) ALI_G


ALI_G
veterán

Nos, van egy kezdeményezésem a megoldásra, amit most nem áll módomban letesztelni.

#! /bin/bash
if test -f $1;
then
_____HOSSZ=`wc -l $1`
_____for ((i=1; i!= $[$HOSSZ+1]; ++i))
_____do
_____head -n $i | tail -n1
_____if [ $i -ge 2 ]; then
__________read
__________clear
_____fi
_____done
else echo ''Nem fájl!''
_____exit
fi


ps.: hiába rakom kódba, a szóközt/tabulálást nem tartja meg, de miért :F

Kérdésem: hol fog ez megbukni? Csak mert amennyire ismerem magam tuti nem fog műxeni :D
Az a bash mélységeibe vájós dolog nekem lehet nem menne, és most nem is tudnám meg se nézni, mert bexart a suliban a server, vagy csak szarakodnak velünk (ált. ZH előtt csinálnak vele vmi gubancot, vagy kötprog leadások előtt, hogy a hallgatónak esélye se legyen befejezni időben :( lassan azt kell hinnem ezt direkt csinálják)

[Szerkesztve]

(#73) Jester01 válasza ALI_G (#72) üzenetére


Jester01
veterán

Nézd meg ngabor2 szkriptjét, a wc sajnos gonosz módon kiírja a fájl nevét is. Szóval a sorszámoláshoz kell a cut is.
A ciklusban nyilván nem jó a $i -ge 2 feltétel (még akkor sem ha az ott tkp 24 akart lenni), hiszen így az első képernyő után már soronként várná az entert.
A for ciklusba a $[$HOSSZ + 1] helyett simán $HOSSZ + 1 kell (vagy egyszerűen i <= $HOSSZ ugye). A head után hiányzik a fájlnév ($1).

MOD: a szóközt tartalmazó fájlok helyes kezeléséhez a megfelelő helyeken idézőjelbe kell tenni a $1-et.

[Szerkesztve]

Jester

(#74) ALI_G


ALI_G
veterán

Van egy elméleti megoldásom. Félig vna csak shell-ben, mert nem volt időm buszon átnézni a szintaktikát (és gyorsan felejtek), de szerintem érthető lesz így is mit akartam.
Íme:

K=wc -l
x=1
for i=1 to K
do
if X<25
head -n i szoveg | tail -n 1 #ez tuti azt csinálja, h minden sort egyesével kiír.
x++
fi
read
X=1
rof


Tudom sok a szintaktikai hiba, de most csak az algoritmus helyessége a lényeg. Ha jó, akkor átírom amint lesz időm, csak holnap egy másik tárgyból ZH-zom. Ezt meg holnap estig kell leadjam.

[Szerkesztve]

(#75) ALI_G


ALI_G
veterán

nah, átírtam shell scripté, kijavítottam pár apróságot:

K=wc -l $1
x=1
for ((i=1;i<=k;i++))
do
if $[ x -lt 25 ]
head -n i szoveg | tail -n 1 #ez tuti azt csinálja, h minden sort egyesével kiír.
x=x+1
fi
read
x=1
done

(#76) Jester01 válasza ALI_G (#75) üzenetére


Jester01
veterán

Ez sajnos még mindig nem jó :(
Amit a wc-vel kapcsolatban írtam, azt nem vetted figyelembe.
A sor kiírás az if elé kell, hiszen azt mindig meg kell csinálni.
A head-bõl kimaradt a $ jel az i elõl, illetve a szoveg helyett $1 kell.
Az if-ben rossz helyen van a $ jel, helyesen if [ $x -lt 25 ] és kimaradt a then.
Az x=x+1 helyesen x=$((x+1))
A read elõtti fi az gondolom inkább egy else, és a fi a done elé való.

k=`wc -l ''$1'' | cut -d\ -f1`
x=1
for ((i=1;i<=k;i++))
do
head -n $i ''$1'' | tail -n 1 #ez tuti azt csinálja, h minden sort egyesével kiír.
if [ $x -lt 25 ]
then
x=$((x+1))
else
read
x=1
fi
done

Jester

(#77) ALI_G válasza Jester01 (#76) üzenetére


ALI_G
veterán

Ok!
bocs, a szoveg benne maradt véletlen :) ezt a sort másoltam. :B
asszem a $ jel elírás volt részemről.

Köszi, remélem mostmár jó lesz.

ps: kirpóbáltam és ilyet kaptam:
cut: invalid delimiter
Ez milyen hiba?! még sose kaptam ezt :O

[Szerkesztve]

(#78) ALI_G


ALI_G
veterán

a delimiter határolójelet jelent. Mostmár ezt is tudom. De legalább a hibás sort számát kiírhatná a linux shellje.

ps:
head -n $i ''$1'' | tail -n 1
ebben a ' ' az miért két karakter és miért nem egy: '' Igaz ugyanúgy néznek ki, de nem mind1 melyiket mikor használjuk. Ez itt jó?

ps2: már látom. valszeg ez lesz a hiba. A PH motorja az idézőjelet két karakterér bontja, vagy az XP vágólapja rosz. Kipróbálom sima idézőjellel, bár nem tudom ide miért is kell.

ps3: ja, mert a fájlban szóközök is lehetnek.

[Szerkesztve]

(#79) ALI_G


ALI_G
veterán

bocs, de megint lejárt a módosítási időlimit.

Ugyanazt a hibát kaptam.
cut: invalid delimiter
:O

(#80) Jester01 válasza ALI_G (#78) üzenetére


Jester01
veterán

Igen, a ph! a ludas ebben :O
A delimiteres hiba a cut-os sorban van, az ott -d\<szóköz><szóköz>-f1 lenne.

Jester

(#81) ALI_G válasza Jester01 (#80) üzenetére


ALI_G
veterán

tényleg, mivel a sok szóközből 1et csinál mindig. De amúgy a code mód miért nem működik, régen ment vele rendesen a kód. nem vágta ki a tab-okat.
Amúgy oda miért kell 2 szóköz?

Amúgy a cut:...nál a cut-ra nem úgy néztem mintha a ódban lenne, hanem aztem a hibamagyarázás része. és mivel még linux buherátor sem vagyok, ezért aztem ilyen szűkszavú a linux, mint mindig is volt.
téháX
most try-olom.

ps: trájoltam, de ez az eredmény copy-ja:
rozi> chmod +x proba.sh
rozi> ./proba.sh bazlaat.sh
rozi>
visszakaptam a shell promtját vagy mit. Nem generált semmilyen látható kimenet. :(

[Szerkesztve]

(#82) Jester01 válasza ALI_G (#81) üzenetére


Jester01
veterán

Azért kell 2 szóköz, mert cut-nak akarjuk megmondani, hogy szóköz legyen a delimiter (ezt a backslash megvédi a shell elõl). A második szóköz pedig a cut argumentumait választja el.

Felraktam az én verziómat a webre: [link].

Jester

(#83) ALI_G válasza Jester01 (#82) üzenetére


ALI_G
veterán

ígymá értem :)
Ha jól láttam ez u.a. mint amit felraktál, még az eredménye is ugyanaz. Nem produkál látható kimenetet a fájl :( visszaadja a promtot.

(#84) Jester01 válasza ALI_G (#83) üzenetére


Jester01
veterán

Akkor ott valami huncutság van, szerintem bele sem megy a ciklusba.
Irasd ki k értékét a ciklus elõtt.

Jester

(#85) ALI_G válasza Jester01 (#84) üzenetére


ALI_G
veterán

eredménye:

rozi> chmod +x ali_g.sh
rozi> ./ali_g.sh bazlaat.sh

rozi>
rozi>


gyanúsan nem lép bele a ciklusba :(((

ps: így néz ki a kód ott:
k=`wc -l ''$1'' | cut -d\ -f1`
x=1
echo $k
for ((i=1;i<=k;i++))
do
...

[Szerkesztve]

(#86) Jester01 válasza ALI_G (#85) üzenetére


Jester01
veterán

Átmenetileg szedd ki a cut-os részt és úgy is nézd meg a k értékét.
Vagy egyszerûen próbáld ki parancssorból wc -l bazlaat.sh illetve wc -l bazlaat.sh | cut -d\ -f1 mit ad.

Jester

(#87) ALI_G válasza Jester01 (#86) üzenetére


ALI_G
veterán

rozi> wc -l bazlaat.sh | cut -d\ -f1

rozi>


Ez az eredménye. Amúgy a bazlaat.sh 900 byteos kb.

rozi> wc -l bazlaat.sh
66 bazlaat.sh
rozi>

[Szerkesztve]

(#88) Jester01 válasza ALI_G (#87) üzenetére


Jester01
veterán

és ha cut<szóköz><idézõjel>-d<szóköz><idézõjel><szóköz>-f1 -et írsz?

Jester

(#89) ALI_G válasza Jester01 (#88) üzenetére


ALI_G
veterán

rozi> wc -l bazlaat.sh | cut ''-d '' -f1

rozi>

Vaj miért vágja le a számot is? :F

[Szerkesztve]

(#90) ALI_G


ALI_G
veterán

uf, ezen kívül van még 1 probléma:
átírtam a k értékét 66-ra, hogy lássam műxik e maga az algoritmus. Íme az eredmény egy részlete (ugyanis végtelen lett vhogy a ciklus):
rozi> ./ali_g.sh bazlaat.sh
66
usage: tail [+/-[n][lbc][f]] [file]
tail [+/-[n][l][r|f]] [file]
usage: tail [+/-[n][lbc][f]] [file]
tail [+/-[n][l][r|f]] [file]
usage: tail [+/-[n][lbc][f]] [file]
tail [+/-[n][l][r|f]] [file]
.......CTRL+C-ig csinálta, ment volna világgá :D

(#91) Jester01 válasza ALI_G (#90) üzenetére


Jester01
veterán

Szerintem valami érdekes verzió van fent a cut és tail parancsokból ami nem támogatja a kapcsolókat amiket használnál.

Jester

(#92) ALI_G válasza Jester01 (#91) üzenetére


ALI_G
veterán

uh hogy a fene enné meg és a fene fenét enne....
Nekem nincs jobb 5letem. Amit még 2 v 3 napja írtál a sima read-es, az meg nehéznek néz ki. Nem hiszem h van arra időm h kihámozzam, de ha nem találok semmit, akkor nekifogok úgy. Bár egyedül kétlem h menne.
Egy kívánságom van: tudjak eccer linuxul. ;]

(#93) Jester01 válasza ALI_G (#92) üzenetére


Jester01
veterán

Kérlek szépen a sima read-es változat az ennyi:

i=0
exec 3<&0
cat ''$1'' | while read line
do
echo ''$line''
if [ $((i++)) -eq 24 ]
then
read <&3
i=0
fi
done

A trükk amit említettem az exec-es sor. A fájlleíróknak linuxban számuk van. A 0,1,2 rendre az stdin, stdout és stderr. A többit arra használod amire akarod. A 3<&0 átirányítás azt jelenti, hogy a 0-ás bemeneti fájlleírót (ami ezek alapján akkor az stdin) duplikálja 3-as számúként.

A while ciklus a pipe miatt alshellben fog futni, aminek az stdin-je a cat stdout-jára van kötve ezért ''elveszik'' a szülõ shell stdin-je (a terminál). Viszont a 3-as számmal ez továbbra is elérhetõ. Vagyis a belsõ read-nek megmondjuk, hogy innen olvasson. (az az átirányítás technikailag azt jelenti, hogy a 3-ast ismét visszaduplikálja a 0-ásra, mivel a read onnan fog olvasni.)

Bonyolultan hangzik, de egyszerû. Remélem érthetõ voltam :F

Jester

(#94) ALI_G válasza Jester01 (#93) üzenetére


ALI_G
veterán

~értlek...vagy legalább is most azt hiszem. Ki is próbálom, de rosszul érzem magam a miatt, hogy ehhez semmi közöm. Bár a tárgy nem számít szinte sehova (azon kívül, hogy kötelező) és senkit se érdekel.
TéHáX! :)

(#95) ALI_G válasza Jester01 (#93) üzenetére


ALI_G
veterán

Tökéletesen működik! :R köszönöm szépen! (bár még mindig zavar, hogy nem magam csináltam. Asszem ezt az exec dolgot én sose tudtam volna meg.)

(#96) Jester01 válasza ALI_G (#94) üzenetére


Jester01
veterán

Nem szokásom komplett megcsinálni mások helyett a feladatot, de te tulajdonképpen megcsináltad, csak azon a gépen nem megy. :R

Jester

(#97) ALI_G válasza Jester01 (#96) üzenetére


ALI_G
veterán

Oh, köszi szépen. Mostmár jobb a lelkiismeretem :) de komolyan. :C

(#98) ALI_G


ALI_G
veterán

re, h úgy mondjam.
El lett fogadva a scriptem. Viszont most újra kell scriptet írjak. Ezt most saját használatra.
A lényeg, hogy ki kell keressek egy mappát. A névben szerepelnie kell a kroc szónak.
Eddig ezem van:

#! /bin/bash
for a in $1/kroc*
do
echo $a
done

Ez sajna nem megy bele az almappákba rekurzívan. Ezt hogy tudom beletenni?

[Szerkesztve]

(#99) Jester01 válasza ALI_G (#98) üzenetére


Jester01
veterán

Ha saját használatra kell, akkor feltételezem nem szükséges shell scriptben implementálni. Egyszerűen find . -type d -name '*kroc*'

Jester

(#100) ALI_G válasza Jester01 (#99) üzenetére


ALI_G
veterán

igen, elég a parancs is.
ki is próbálom

ps:
eredmény:
rozi> find . -type d -name '*kroc*'
find: cannot read dir ./aset: Permission denied
find: cannot read dir ./local/etc/amanda: Permission denied
find: cannot read dir ./local/var/openldap-ldbm: Permission denied
find: cannot read dir ./local/var/openldap-slurp: Permission denied
find: cannot read dir ./local/var/amanda: Permission denied
rozi>

:( ez azt jelenti, hogy nem talált ott ahol próbálta? az az 5 pedig védett és nem mehetett bele?

[Szerkesztve]

Copyright © 2000-2024 PROHARDVER Informatikai Kft.