Hali!
Adott egy konyvtar, amiben van tobb alkonyvtar, azokban tobb file. Bizonyos file-okban bizonyos szoveget le akarok cserelni ("ISO-8859-1"-et "UTF-8"-ra, de nem HTML vagy PHP fileok, config fileok. Itt az elso probaban meg nem is akarok cserelni, csak cat segitsegevel elolvasni ezeket a file-okat.)
Elso otlet:
grep -r keresem * | awk '{print $}' > tmpfile
while read ; do cat $REPLY ; done < tmpfile
Ez ugye visszadna "tmpfile"-ban azon file-ok neveit, amiben benne van a "keresem" szo, masodik sor pedig elolvasna ezeket a file-okat.(Nem az, amit en akarok, de ezen konnyebben mutatom). Es itt jon a bibi: a filenevek szokozt tartalmaznak . Tobb probam is volt:
grep -r keresem * | awk '{print $}' | sed '/\ /\\/g' > tmpfile
a tmpfileban gyonyoru:
xx/yy/file\ neve
De ha ugyanezt beolvastatom a "while read" paranccsal, valami ertelmezi a "\" jelet es eltunteti :(
Valami otlet? Persze, megcsinalhatnam, hogy mondjuka "detox" proggival eltuntetem az osszes szokozt es ugy futtatom, csak sajnos ezek a file-ok havonta frissulnek :(
- 1270 megtekintés
Hozzászólások
Probald meg lecserelni a sed delimitereit valami masra, pl:
sed -e 's|cucc|masikcucc|g'
Korantsem biztos, hogy ez a baj, de egy probat meger.
- A hozzászóláshoz be kell jelentkezni
"$REPLY" a megoldás, tehát "-ök közé kell tenni,
nekem amúgy az awk-s cucc nem megy, biztos elírtad, én cut-ot szoktam ilyen dolgokra használni, ilyesmiképp:
cut -f 1 -d ':'
Update: meg ilyen is van: grep -lr valami .
- A hozzászóláshoz be kell jelentkezni
REPLY-t megnezem.
Awk tenyleg rossz:
awk -F: '{print $1}' lenne.
- A hozzászóláshoz be kell jelentkezni
Ijjj, koszi, tenyleg "$REPLY" a jo :)
Mit gorcsoltem, mire ide irtam, es ilyen halal egyszeru :)
Volt ilyen is:
while read ; do cat `echo -e $REPLY |sed 's/\ /\\ /g'` ; done < x
- A hozzászóláshoz be kell jelentkezni
Ujabb, hasonlo problemam akadt, csak most mplayerrel. Itt egy file reszlete, ami a parameterknet megkapott kiterjesztesu filokat kigyujti egy listaba, aztan az mplayer vegigszalad rajta, hoyg kideritse az audio/video codecet es bitratat. Gondoltam, rakok bele egy szamlalot is, hogy lassam, hol tart :)
DB=$(ls *$1 | wc -l) #DB file
ls *$1 > ListAbA #filenevek
AKT=1 # aktualis
while read # ciklus
do echo $AKT'/'$DB # hanyadiknal tart
do echo $REPLY # Melyik a file
mplayer -ao null -vo null -endpos 1 $REPLY 2>/dev/null| grep 'Playing\|kbps\|kbit' >> bitrate0.log
AKT=$(expr $AKT + 1) # kovetkezo file
done < ListAbA # es ennyi.
A vicc az, hogyha az mplayer kezdetu sort kikommentezem, akkor gyonyoruen azt csinalja, amit akarok, kiirja az osszes filenevet egyesevel. Ha bent van az mplayer sor, akkor csak a legelso filet nezi meg (de tovabb szamlal, viszont az mplayer olyan, mintha nem kapna filenevet.
Ez viszont gyonyoruen mukodik, szoval a meghivott kiterjesztesu fileokat atnezi.
#mplayer -ao null -vo null -endpos 1 *$1 2>/dev/null| grep 'Playing\|kbps\|kbit' >> bitrate0.log
Mi a nyavalyatol lehet ez?
- A hozzászóláshoz be kell jelentkezni
Jaigen, a filenevekben nincs speci karakter, nincs szokoz, csak kis- es nagybetu, alahuzasjel vagy kotojel es egyetlen pont, a kiterjesztes elott. Es itt a "REPLY" sem mukodik, hiaba rakom idezojelbe :(
- A hozzászóláshoz be kell jelentkezni
Szerintem először jó lenne a copy-paste-elést gyakorolni, mert az a két do ott alant eleve kizárja, hogy ez ne szálljon el syntax errorral.
while read # ciklus
do echo $AKT'/'$DB # hanyadiknal tart
do echo $REPLY # Melyik a file
...
done
- A hozzászóláshoz be kell jelentkezni
naigen. Gondolatban huzd ki belole es ugorgyunk.
- A hozzászóláshoz be kell jelentkezni
Kihúztam. Megtennéd, hogy code tagok közé tényleg bemásolod - és akkor nekiugrunk.
- A hozzászóláshoz be kell jelentkezni
Ha gondolatban kihúzom, akkor nálam gondolatban "$REPLY", és működik...
- A hozzászóláshoz be kell jelentkezni
Oke, akkor ez a (nem) mukodo.
DB=$(ls *$1 | wc -l) #DB file
ls *$1 > ListAbA #filenevek
AKT=1 # aktualis
while read # ciklus
do echo $AKT'/'$DB # hanyadiknal tart
mplayer -ao null -vo null -endpos 1 $REPLY 2>/dev/null| grep 'Playing\|kbps\|kbit' >> bitrate0.log
AKT=$(expr $AKT + 1) # kovetkezo file
done < ListAbA # es ennyi.
Ha az mplyaer sor helyett a kovetkezo van, gond egy szal sem:
echo $REPLY # Melyik a file
Sot. Itt az alabbi file, ami mukodik :
#!/bin/sh
while read
do
t=`echo $REPLY | awk '{print $1}'`
v=`echo $REPLY | awk '{print $2}'`
a=`echo $REPLY | awk '{print $3}'`
nt=`echo $REPLY | awk '{print $4}'`
rm frameno.avi
rm divx2pass.log
mencoder $t -mc 0 -oac mp3lame -ovc frameno -o frameno.avi -lameopts cbr:br=$a 1> $t.0.log 2>&1
echo "$t 0 menet kesz" >> code.log
mencoder $t -oac copy -mc 0 -ovc xvid -o $nt -xvidencopts bitrate=$v:pass=1 1> $t.1.log 2>&1
echo "$t 1 menet kesz" >> code.log
mencoder $t -oac copy -mc 0 -ovc xvid -o $nt -xvidencopts bitrate=$v:pass=2 1> $t.2.log 2>&1
echo " $t .2 menet kesz" >> code.log
done < bitrate.log
bitrate.log fileban vannak felsorolva a filmek
nev TAB video_bitrata TAB audio_bitrata TAB uj_nev
nev TAB video_bitrata TAB audio_bitrata TAB uj_nev
.
.
Es gyonyoruen vegigmegy a file-on sorban atkodolva a filmeket (mpg-bol vagy wmv-bol szoktam avit csinalni). Tehat ez a code azt csinalja, amit szeretnek, mig a fenti nem.
De akar ki is probalhatjatok, 3-4 film egy konyvtarba, raengedni az elso kodot, kivancsi vagyok, csak nalam nem mukodik, vagy mashol sem...
- A hozzászóláshoz be kell jelentkezni
szerintem szokd meg, hogy a file-ok sokasagan vegigmeno ciklus az mindig find -print0 | while read -r -d $'\0', es a ciklus belsejeben mindig "$REPLY"
DB=$(ls *$1 | wc -l) #DB file
AKT=1
#ls *$1
find . -name "*$1" -print0 -maxdepth 1 |
while read -r -d $'\0'
do echo $AKT'/'$DB # hanyadiknal tart
mplayer -ao null -vo null -endpos 1 "$REPLY" 2>/dev/null |
grep 'Playing\|kbps\|kbit' >> bitrate0.log
AKT=$(expr $AKT + 1) # kovetkezo file
done # es ennyi.
ha nem csak az aktualis dirben, hanem rekurzivan az osszes alatta levo dirben is szeretned ezt megoldani, akkor hagyd el a "-maxdepth 1" kapcsolot a find parancsbol.
- A hozzászóláshoz be kell jelentkezni
a problema komoly, a szerteagazo gyermek-problemak sok kedves hacker munkajat tettek mar lehetove a vilagban. Erre az alapproblemara a megoldas:
find | xargs
vagy find | while read
visoznt ez elesik a whitespacen, mint minden, es a file neve tartalmazhat ujsor karaktert is (igazabol csak '\0' es '/' karektereket nem tartalmazhat) Erre van egy gnu extension (linuxokon van) ez a print0 es tarsai. Ezek a find kimenetet '\0'-val szeparaljak (ami invalid file char) tehat nem lesz utkozes. A
read -d $'\0'
meg kifejezetten bash, szoval nem tul portabilis, de linuxon jok ezek.
find -print0 | xargs -0 -L1 command
find -print0 | while read -r -d $'\0' ; do command "$REPLY" ; done
Okes, itt egy cklus, ami helyesen vegig megy a fileokon, hasznaljuk ezt. Nezzuk most a feladatot: csak azon file-ok, amiben szerepel a keresett kifejezes:
find -print0 |
while read -r -d $'\0' ; do
if grep -q 'keresem' "$REPLY" ; then
sed -i -e 's/keresem/erre/g" "$REPLY"
fi
done
a megoldas lassabb, mintha a grep lenne kivul (a grep tobbszori meghivasa miatt) azonban az esetleges sorvegjeleket nem tudom mashogy hogyan megoldani.
Ja, a
sed -i
is gnu specific ha jol emlekszem.
- A hozzászóláshoz be kell jelentkezni
Koszi, igy utolag is. Az elsovel a gondom ugy oldodott meg, hogy a REPLY idezojelek koze kerult. De most mas a gondom, csak nem akartam neki uj topicot inditani:
Az mplayer nem hajlando ertelmezni a REPLY-t rendesen...
- A hozzászóláshoz be kell jelentkezni
De ha ugyanezt beolvastatom a "while read" paranccsal, valami ertelmezi a "\" jelet es eltunteti :(
man bash (tudom, hosszu) read builtin:
-r Backslash does not act as an escape character. The back-
slash is considered to be part of the line. In particu-
lar, a backslash-newline pair may not be used as a line
continuation.
- A hozzászóláshoz be kell jelentkezni
Tenyleg hosszu :) Koszi, ezt az -r kapcsolot felirom magamnak.
- A hozzászóláshoz be kell jelentkezni