Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: Příkaz "find" v cyklu for... [vyřešeno]  (Přečteno 3397 krát)

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Příkaz "find" v cyklu for... [vyřešeno]
« kdy: 27 Dubna 2009, 08:29:45 »
1, Když zadám

Kód: [Vybrat]
ladik@ladik:/$ find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*
/home/ladik/cvert/fotky/BLA ěčříěĚÉÉŘŮW
/home/ladik/cvert/ěčř žř ýěěě
/home/ladik/cvert/žřš ýžř áŠŘŽŘ
ladik@ladik:/$ 

= najde, co hledám...

Když zadám to samé, ale nacházím se v $HOME a ne v kořenovém adresáři "/", tak

Kód: [Vybrat]
ladik@ladik:~$ find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*
find: paths must precede expression: Condition Zero.desktop
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
ladik@ladik:~$ 

tak vypíše chybu..ve skriptu jsem to sice vyřešil tak, že před hledáním zadám "cd /", ale i tak by mě zajímalo, proč to..?

2, Ve skriptu v cyklu for..in..do..done se tento příkaz zase chová kapku jinak..normálně vypíše nalezené soubory ve tvaru, v jakém ty soubory jsou..Když to dám do cyklu for, tak...

Kód: [Vybrat]
ladik@ladik:~$ zko
/home/ladik/cvert/fotky/BLA
ěčříěĚÉÉŘŮW
/home/ladik/cvert/ěčř
žř
ýěěě
/home/ladik/cvert/žřš
ýžř
áŠŘŽŘ
ladik@ladik:~$
 

skript vypadá takhle:
Kód: [Vybrat]
#!/bin/bash

cd /

   for i in `find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*`; do
echo $i
   done

Oč mi jde je asi jasné, chci vyhledat soubory s diakritikou a následně je přejmenovat...nejdřív ale musím docílit toho, aby mi příkaz find vyhodil na výstup soubory ve správném tvaru. Proč ale v cyklu for ty soubory rozkouskuje po mezerách a na každý řádek vyhodí část názvu souboru?

Když zadám do toho skriptu ještě dvojí uvozovky, takhle

Kód: [Vybrat]
for i in "`find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*`"; do
tak už to sice vypíše název souboru ve správném tvaru, ale zase je to všechno na jednom řádku:

Kód: [Vybrat]
ladik@ladik:~$ zko
/home/ladik/cvert/fotky/BLA ěčříěĚÉÉŘŮW /home/ladik/cvert/ěčř žř ýěěě /home/ladik/cvert/žřš ýžř áŠŘŽŘ
ladik@ladik:~$ 

jsem z toho jakýsi volako zmatený, věděl by někdo důvod prosím?
« Poslední změna: 28 Dubna 2009, 15:00:09 od On »
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

nettezzaumana

  • Host
Re: Příkaz "find" v cyklu for...
« Odpověď #1 kdy: 27 Dubna 2009, 08:44:08 »
ad.1) for x in "1 2"; do echo $x; done ## vypise "1 2" protoze for probiha pouze v jednom cyklu, stejne jako kdyz zadas
for x in "$(foo)"; do .. ## kdy vystup z $(foo) se bude brat jako jeden parametr i kdyby jich bylo vic

ad.2) `find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*`, zda se mi, ze je spatne neb u me to nepracuje jak ma ..

ad.3) pro tento ucel je whodnejsi pouzit while aka ::

while read line; do foo; done < <(bar) ## a nebo
bar | while read line; do ..; done

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Re: Příkaz "find" v cyklu for...
« Odpověď #2 kdy: 27 Dubna 2009, 09:04:22 »
No, s těma apostrofama to právě nefunguje, jak má..když tento příkaz ale zadám to terminálu ručně:

Kód: [Vybrat]
ladik@ladik:/$ find $HOME/cvert -type f -iname *[" "ěščřžýáíéóúůďňť]*
/home/ladik/cvert/fotky/BLA ěčříěĚÉÉŘŮW
/home/ladik/cvert/ěčř žř ýěěě
/home/ladik/cvert/žřš ýžř áŠŘŽŘ

tak spolehlivě vyhledá, co potřebuju...
Zkusím to tím while..
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

kkaarreell

  • Stálý člen
  • **
  • Příspěvků: 1072
Re: Příkaz "find" v cyklu for...
« Odpověď #3 kdy: 27 Dubna 2009, 09:55:34 »
Podle me je problem v tom, ze ten nazev souboru obsahujici wildcards (hvezdicka a spol) neobalis apostrofem. Tyto znaky tak expanduje jiz primo shell a ne prikaz find (coz bys chtel ty) - predpokladam, ze narozdil od adresare / mas v ~ nejaky soubor s diakritikou (a pravdepodobne ne jeden) a buh vi, co se nakonec dostane k tomu findu (rekl bych, ze vice parametru, nez find ceka, proto ta hlaska).

spravne se totiz hleda
Kód: [Vybrat]
find ~ -name '*.txt'a ne
Kód: [Vybrat]
find ~ -name *.txt

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Re: Příkaz "find" v cyklu for...
« Odpověď #4 kdy: 27 Dubna 2009, 10:18:42 »
tak vzhledem k tomu, že přepis diakritiky budu používat kdekoliv jinde, jen ne v "/", tak nevadí, když na začátek skriptu, před hledáním, dám "cd /", tím se tohle vyřeší...sice mi moc není jasné proč, ale nevadí, hlavně, že najde... Našel jsem skript na odstranění diakritiky někde na netu, ale on přepisuje všechno co najde..tzn když nějaký soubor diakritiku neobsahuje, tak ho započítá a "přepíše" ho na ten samý název..takže s ním sice nic neudělá, ale zbytečně se vytěžuje :) Chci si to teda vytvořit sám s tím, že bude přepisovat jen ty soubory, které budou obsahovat "nepovolené" znaky..jak přijdu domů, zkusím polaborovat s tím while, to by mohlo fungovat..S tím "bar", to sice nevím k  čemu slouží, ale to už google poradí
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Re: Příkaz "find" v cyklu for...
« Odpověď #5 kdy: 27 Dubna 2009, 18:00:21 »
No, tak moc jsem se s panem "while" v kombinaci s "bar" nezkamarádil...sice jsem to vyřešil, ale rozhodně ne způsobem, kterým bych se mohl chlubit..bohužel to mám ve dvou souborech. Zkusím ještě zalaborovat, jak to udělat v jednom, já na to přijdu, jen to chce čas :)

jinak jsem to teda vyřešil tak, že jeden soubor slouží k prohledávání:

Kód: [Vybrat]
#!/bin/bash

  while :; do

echo -n "Zadej cestu pro přejmenování souborů: "
read cesta

cd $cesta &> /dev/null
if [ $? -eq 0 ]; then break
else echo Cesta neexistuje
fi
  done

cd /
find $cesta -type f -iname *[" "ěščřžýáíéóúůďňť]* -exec $HOME/Programovani/diakritika {} \;

..a ve druhém skriptu je zbytek:

Kód: [Vybrat]
#!/bin/bash

      echo "-----------------------------------------------------------------"
    echo Přejmenovávám:
  echo $1
 jmeno=`echo $1 | sed 's/ /_/g' | sed 's/á/a/g' | sed 's/Á/A/g' | sed 's/č/c/g' | sed 's/Č/C/g' | sed 's/ď/d/g' | sed 's/Ď/D/g'| sed 's/é/e/g' | sed 's/É/E/g' | sed 's/ě/e/g' | sed 's/Ě/E/g' | sed 's/í/i/g' | sed 's/Í/I/g' | sed 's/ň/n/g' | sed 's/Ň/N/g' | sed 's/ó/o/g' | sed 's/Ó/O/g' | sed 's/ř/r/g' | sed 's/Ř/R/g'  | sed 's/š/s/g' | sed 's/Š/S/g' | sed 's/ť/t/g' | sed 's/Ť/T/g' | sed 's/ú/u/g' | sed 's/Ú/U/g' | sed 's/ý/y/g' | sed 's/Ý/Y/g' | sed 's/ž/z/g' | sed 's/Ž/Z/g' | sed 's/ů/u/g' | sed 's/Ů/U/g'`
 echo Na soubor:
  echo $jmeno
    mv "$1" "$jmeno"
      echo "-----------------------------------------------------------------"
       

trapné, já vím, ale účel plní :)..aspoň na chvilku, než to trochu přetvořím
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

nettezzaumana

  • Host
Re: Příkaz "find" v cyklu for...
« Odpověď #6 kdy: 27 Dubna 2009, 23:00:08 »
Citace
#!/bin/bash

#!#!#!#!# heh. `brake` do slovniku slusneho hocha nebo devcete rozhodne nepatri !!

#  while :; do

#echo -n "Zadej cestu pro přejmenování souborů: "
#read cesta

#cd $cesta &> /dev/null
#if [ $? -eq 0 ]; then break
#else echo Cesta neexistuje
#fi
#  done

#cat << 'EOF' >/tmp/foo
##!/bin/bash
#
#      echo "-----------------------------------------------------------------"
#    echo Přejmenovávám:
#  echo $1
# jmeno=`echo $1 | sed 's/ /_/g' | sed 's/á/a/g' | sed 's/Á/A/g' | sed 's/č/c/g' | sed 's/Č/C/g' | sed 's/ď/d/g' | \
#sed 's/Ď/D/g' |sed 's/é/e/g' | sed 's/É/E/g' | sed 's/ě/e/g' | sed 's/Ě/E/g' | sed 's/í/i/g' | sed 's/Í/I/g' | \
#sed 's/ň/n/g' | sed 's/Ň/N/g' | sed 's/ó/o/g' | sed 's/Ó/O/g' | sed 's/ř/r/g' | sed 's/Ř/R/g'  | sed 's/š/s/g' | \
#sed 's/Š/S/g' | sed 's/ť/t/g' | sed 's/Ť/T/g' | sed 's/ú/u/g' | sed 's/Ú/U/g' | sed 's/ý/y/g' | sed 's/Ý/Y/g' | \
#sed 's/ž/z/g' | sed 's/Ž/Z/g' | sed 's/ů/u/g' | sed 's/Ů/U/g'`
# echo Na soubor:
# echo $jmeno
#    mv "$1" "$jmeno"
#      echo "-----------------------------------------------------------------"
#EOF

#find $cesta -type f -iname *[" "ěščřžýáíéóúůďňť]* -exec /tmp/foo {} \;

## ps. navic se vsadim, ze minimalne s mezerama v nazvech souboru se to bude chovat znacne nevypocitatelne ..

#!#!#!# a co takhle?

## dokud nemame existujici cestu
## tak te vyzveme at ji zadas
## precteme si cos nam dal. viz. `man bash`
## a pokud to neni platna cesta
##   .. tak to zahodime
## a dame ti dalsi sanci ..

while test -z "$cesta"; do
   echo -n "zadej cestu: ";
   read -e cesta;
   if test ! -d "$cesta"; then
      unset cesta;
   fi
done

## dame vypisovat obsah cesty a dokud se tak bude dit,
## ulozime si, jak bude aktualni polozka vypadat po zmene pismen
## a pokud se lisi od vychozi cesty dle origanalu
##    .. tak s ni neco provedeme
## a pokracujeme na dalsi cestu ..

find "$cesta" | while read line; do
   changed="$(echo "$line" | sed 'y/ěščřžýáíé/escrzyaie/');"
   if test "$changed" != "$line"; then
      echo -e "cp \"$line\" \"$changed\"";
   fi
done

## dale viz.: http://en.wikipedia.org/wiki/Foobar
« Poslední změna: 27 Dubna 2009, 23:41:24 od nettezzaumana »

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Re: Příkaz "find" v cyklu for...
« Odpověď #7 kdy: 28 Dubna 2009, 07:23:32 »
Heh...ono to vážně funguje...to "EOF" asi teda bude k něčemu dobré, už jsem o tom četl, ale přišlo mi to až moc pokročilé, tak jsem tu kapitolu jaksi přeskočil...tak se k tomu teda vrátím :)

Ta tvoje verze je jakási menší a dokonce jsem se v tom kódu už i vyznal, to je chytré.

A ještě dotaz...

Citace
#!#!#!#!# heh. `brake` do slovniku slusneho hocha nebo devcete rozhodne nepatri !!

...ani break? :) Vím, žes mě na to už jednou upozorňoval, to je jen nějaká programátorská hantýrka nebo proč se to "nepoužívá"? Jestli to ale má stejný význam, jako rozjíždění u auta, tak bych to i pochopil, tzn:

Rozjet se taky dá se zařazenou rychlostí a bez plynu, ale nepoužívá se to :)
« Poslední změna: 28 Dubna 2009, 07:26:31 od On »
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

nettezzaumana

  • Host
Re: Příkaz "find" v cyklu for...
« Odpověď #8 kdy: 28 Dubna 2009, 12:37:57 »
Citace
#!#!#!#!# heh. `brake` do slovniku slusneho hocha nebo devcete rozhodne nepatri !!
yes!! no more breakes ..

ad.x) vsimni si, ze cerne komentare ode me line-by-line presne popisuji co dela kod pod nimi, takze by bylo s podivem, abys tomu nerozumel ..

ad.y) tve dve veci jsem si dovolil (modrym pismem) shrnout do jedne ..

ad.z) nemam rad a ani nepouzivam interaktivni skripty !! snazil jsem se jen nazorne ukazat bez premysleni o zadani jak tve zadani vyresit ..

On

  • Stálý člen
  • **
  • Příspěvků: 1136
    • Operační systémy
Re: Příkaz "find" v cyklu for...
« Odpověď #9 kdy: 28 Dubna 2009, 14:59:54 »
jj, to je právě ten rozdíl mezi náma...já nad tím kódem, co ty vyplivneš za 10 vteřin, bádám jednu pracovní směnu :) O to větší je ale motivace, když to funguje..

ad.x) na mou obhajobu musím říct, že se v rámci výuky nejdřív snažím přeluštit kód a pak si to samozřejmě nechám pod černými komentáři potvrdit :P

Každopádně se toto vlákno myslím dá označit za "vyřešeno"...už mám v plánu další skript a už teď vím, kde bude zádrhel...zkusím na to ale přijít, při nejhorším asi zase zaškemrám o pomoc


díky
« Poslední změna: 28 Dubna 2009, 15:03:31 od On »
Asus M2A-VM HDMI, Athlon 64 X2 4800+, 4GB DDR2/800Mhz,Powercolor HD 2600 XT, Ubuntu 10.10
Být posledním nevadí, ale nikdy nesmíte být poslední dvakrát po sobě - Iacocca

nettezzaumana

  • Host
Re: Příkaz "find" v cyklu for... [vyřešeno]
« Odpověď #10 kdy: 28 Dubna 2009, 15:45:53 »
snazil jsem se ti jen rict, ze `if [ $? -eq 0 ]; then break` je nesmysl, protoze cykly se pouzivaji jako

while vyraz(); do akce(); done

.. aka `while echo ahoj; do sleep 1; done`, vyraz se overuje kazdy prubeh a implicitne se jedna o $?



starenka

  • Stálý člen
  • **
  • Příspěvků: 1276
  • Karma: plynová [zapalovač] [hasičák]
    • /home/starenka
Re: Příkaz "find" v cyklu for... [vyřešeno]
« Odpověď #11 kdy: 28 Dubna 2009, 17:40:13 »
nechci se vam tady do toho navazet, ale neni lepsi nez nejaky vycty co za co nahradit na to pustit iconv  a na cilovy kodovani hodit ASCII//TRANSLIT ?

konkretne:

Kód: [Vybrat]
starenka@kosmik1:/junk/test$ echo řšžčšťďfňěíéáýŽ | iconv -f utf-8 -t ascii//translit
rszcstdfneieayZ
« Poslední změna: 28 Dubna 2009, 17:47:21 od starenka »
mojenka | blozinek v2 | starej blozinek | krotim hady za penize | UJ! Kalužátor

Debian testing vrní v Thinkpadu X200/bedně/EEE 900a, MasoX Tiger v lampe

 

Provoz zaštiťuje spolek OpenAlt.