Odštampaj stranicu - BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?

Linuxo Forumi

Linux => Programiranje => Temu započeo: foxbunny 01 Мај 2008, 18:19:56



Naslov: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 01 Мај 2008, 18:19:56
Recimo, imam fajlove:

$PWD/zivotinje/maca
$PWD/zivotinje/kuca
$PWD/zivotinje/zirafa
$PWD/zivotinje/sibirski\ haski
$PWD/stvari/solja
$PWD/stvari/kasica

I sad, hocu sve te stvari da iskopiram u folder

/neki/tamo/folder

Ja probao ovo:

for i in $(find $PWD ! -type d -print | sed 's/ /\\ /g')
do
    cp $i /neki/tamo/folder
done

Medjutim, kad to uradim, onda mi "$PWD/zivotinje/sibirski\ haski" tretira kao "$PWD/zivotinje/sibirski\" i "haski" i onda se buni kako ti falovi ne postoje.

Da li neko zna kako da resim ovaj problem?


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: milosk 01 Мај 2008, 18:32:43
Hehe, ovo se zove zakucavanje ekserčića pneumatskim čekićem  :D

Probaj samo cp -R, ili još bolje -a


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Владимир 01 Мај 2008, 18:56:41
@milosk
Hmm, koliko ja vidim on hoće sve fajlove i samo fajlove, da kopira u isti direktorijum.


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: milosk 01 Мај 2008, 19:08:13
@Владимир
U pravu si kad bolje pročitam, znači hoće da ih "sravni".

Možda treba $i zaviti u navodnike, mada uvek pomešam koje pa obično probam sve tri varijante: "...", '...', i obrnute `...`


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: RiSK 01 Мај 2008, 19:25:19
Ma 'double quotes' ili naski navodi se koriste za to. Treba da boravi "$i"


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: foxbunny 01 Мај 2008, 19:30:44
Obrnuti se nesto cudno ponasaju, i na prvi pogled ne mogu da skapiram sta se desava sa stringovima. Ovi jednostruki ne mogu posto ne podrzavaju interpolaciju, a ovi dupli ne postizu nista.

Ma, nesto se meni cini da vec kod

for i in $(...)

on razdvaja stringove po razmacima.


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 01 Мај 2008, 19:33:35
BTW, kad smo vec kod shell programiranja, sta vi mislite o zsh shellu?


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: RiSK 01 Мај 2008, 20:00:41
Back-quotes sluze za razvijanje stringa u komandu. Sve sto je izmedju dva back-quota (`) se tretira kao komanda, zatim se izlaz te komande stavlja na mesto gde je bio unos apostrofima i ponovo izvrsava kao komanda.
Evo primer da ti bude jasnije: Kada ukucas
Kod:
echo dmesg
Ispuisacese red u kome pise dmesg (da ne poverujes :))
Kada ukucas
Kod:
`echo dmesg`
Desice se sledece: bash razvija komandu ovicenu znacima obrnutih navoda. Komanda izmedju dva znaka ` se izvrsava. Izlaz te komande se, zatim, pise na mesto same komande. Izlaz komande "echo dmesg" je samo "dmesg", tako da ce se pocetka komanda komanda razviti u komandu
Kod:
dmesg
i ova ce se izvrsiti tako da joj izlaz bude prikazan u terminalu.

Valjda sam ti nesto objasnio :)

Strong-quotes (apostrof) i soft-quotes (navodnici) se razikuju po tome sto se ispod apostrofa ne razvija nista, dok se ispod navoda razvijaju promenljive. Npr.
Kod:
echo '$HOME'
stampa $HOME a
Kod:
echo "$HOME"
stampa tvoj home direktorijum.

Sto se tice skripte, da greska je u zaglavlju ciklusa. Tek sada sam pogledao sta ti ustvari radis.

Ovo sto hoces da uradis se radi malo elegantnije. Kmanda find ima svic -exec kojom se navedena komanda primenjuje na jedan od izlistanih fajlova. Slicnu stvar (neki kazu efikasnije) mozes izvesti kombinacijom find|xargs.

Komanda koja menja ciklus i find bi trebala da izgleda ovako:
Kod:
cd /sta/kopiras && find -exec cp {} /gde/kopiras/ \;
Pogledaj man strane za find i xargs za vise informacija. Imas dobro citanje i ovde http://www.bsd-srbija.org/dokumentacija/doku.php/koriscenje_find_komande

Sto se tice zsh-a odlican je, ali pre svega za interaktivan rad. Ima gomilu completitiona, prepravki i dzidzamidza. Obozavbam ga sto se toga tice. Za skripte nema nikakvu prednost nad bash-om (za sve sto ima viska u odnosu na bash postoji zaobilaznica). Sa druge strane glomazniji je i sporije se izvrsava. Tako da skriptuj u bashu ;)


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 01 Мај 2008, 20:05:06
Ok, hvala. Nisam znao za te viticaste zagrade {} u -exec argumentu. Ali ono, glupo bi bilo da ih nema, kad bolje razmislim. Hvala, RiSK, pomogao si mi BASH dosta. :D


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: RiSK 01 Мај 2008, 20:20:08
Ma nema na cemu. Tu smo da se pomazemo koliko mozemo.
Srecno bashanje ;)


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 01 Мај 2008, 20:45:45
Hm, evo ovako:

$  find $PWD -name '*.pdf' -exec cp {} /home/blackfox/shares/ebooks/ ;
find: missing argument to `-exec'

$  find $PWD -name '*.pdf' -exec cp {} /home/blackfox/shares/ebooks/\;
find: missing argument to `-exec'

Sta sam sad propustio?


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 01 Мај 2008, 21:11:50
Sto bi reko narod "mamicu mu njegovu". A lepo pise u dokumentaciji "READ THE F'CKING EXAMPLES SECTION, YOU F'CKING MORON!"

U svakom slucaju,

find $PWD -name '*.pdf' -exec cp '{}' /home/blackfox/shares/ebooks/ \;

Bez tih jednostrukih navodnika nije hteo da radi.


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: soxxx 02 Мај 2008, 17:33:22
Mislim da si u predhodnom postu u prvom primeru zaboravio kosu crtu ispred tacke i zareza; a u drugom primeru nisi ostavio prazno polje izmedju kose crte i tacke i zareza. Kod mene javlja drugu gresku ali je moguce da se greske razlikuju.

-print izlistava fajlove i odvaja ih praznim poljem kada se izlaz prosledjuje drugoj komandi i ovo moze da predstavlja problem.

Ako imas dosta fajlova prednost je da se koristi xargs zato sto ne pokrece (forkuje) poseban proces za svaki fajl kao sto to radi -exec, kao sto je RiSK rekao. Medjutim xargs se ne snalazi bas najbolje ponekad sa fajlovima koji imaju prazno polje u imenu. Onda moze da se koristi "find . -print0 | xargs0 komanda".
Jos jedno (POSIX) resenje za ovaj problem sa praznim poljima u imenima fajlova je "-exec +". Pogledaj man stranice. ;) Evo ti jedan tutorijal za find (pogledaj i onaj link koji ti je RiSK ostavio):

http://www.hccfl.edu/pollock/Unix/FindCmd.htm

Pozdrav


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 02 Мај 2008, 22:15:31
Mislim da si u predhodnom postu u prvom primeru zaboravio kosu crtu ispred tacke i zareza; a u drugom primeru nisi ostavio prazno polje izmedju kose crte i tacke i zareza. Kod mene javlja drugu gresku ali je moguce da se greske razlikuju.

Pa probao ja sve to, ali poenta je izgleda bila u tim jednostrukim navodnicima. To sam tek kasnije video iz primera da mora.

-print izlistava fajlove i odvaja ih praznim poljem kada se izlaz prosledjuje drugoj komandi i ovo moze da predstavlja problem.

Ma znam, ali ostale print varijante su mi vec ono. print0 je u okvrisu skripta proizvodio identican rezulat, a ono sa formatiranjem... Hm, lakse mi da iskodiram u Pythonu sve to. ;)

Ako imas dosta fajlova prednost je da se koristi xargs zato sto ne pokrece (forkuje) poseban proces za svaki fajl kao sto to radi -exec, kao sto je RiSK rekao. Medjutim xargs se ne snalazi bas najbolje ponekad sa fajlovima koji imaju prazno polje u imenu. Onda moze da se koristi "find . -print0 | xargs0 komanda".
Jos jedno (POSIX) resenje za ovaj problem sa praznim poljima u imenima fajlova je "-exec +". Pogledaj man stranice. ;) Evo ti jedan tutorijal za find (pogledaj i onaj link koji ti je RiSK ostavio):

http://www.hccfl.edu/pollock/Unix/FindCmd.htm

Pozdrav

Hvala za linkove i tebi i RiSKu. Naravno, prostudiracu ih zajedno sa man stranicama. Tek kad krene ovako da se petlja, covek shvati kolika je faca onaj link sto napravi Total Commander. :D


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Časlav Ilić 03 Мај 2008, 11:29:41
Pored toga što ne pokreće novi proces za svaki argument (osim ako baš hoćemo), meni je obrazac find ... | xargs ... zgodniji od find ... -exec i po tome što mogu dodatno da filtriram ono što find nađe. Na primer, ako tvom slučaju dodam da hoću da izbacim datoteke koje sadrže .svn/ u imenu:
Kod:
$ find odredisni/dir/ -type f -print0 | grep -Zz -v '\.svn/' | xargs -0 cp -t ciljni/dir/
(opcija -t uz cp obrće redosled argumenata, tj. cp -t ciljni/dir/ datoteke — mogu da se opkladim uvedeno baš radi xargs :)


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 03 Мај 2008, 11:33:20
find ima podrsku za regexp, tako da ne moras ni da grepujes. ;)


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Časlav Ilić 03 Мај 2008, 12:01:10
Jest, al' su njegovi regizovi ružniji od grepovih (posebno grep -E, tj. egrep), u ovom primeru bi bilo nešto kao ! -regex '.*\.svn/.*'. Drugo, možda i ne želim da grepujem pre obrade, već nešto peto (npr. sortiram, ili čak grepujem po sadržaju, grep -liI). Treće, možda mi je za krajnju naredbu baš i neophodno da se pozove sa svim pronađenim datotekama, a ne samo radi brzine. Kad se sve sabere, prosto se ne hvatam za te „napredne“ mogućnosti find, a vidim da i inače ljudi to ne čine po skriptama.

(Doduše, pročitao sam negde da find ... -exec može biti korisno u slučajevima kada je bitna bezbednost, da se ništa ne umeša u cevku.)


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktorijum?
Poruka od: foxbunny 03 Мај 2008, 13:44:16
Pa naravno, to je poenta Unix shella, uvek mozes da pajpujes. To jest, ako ne mozes, onda ta komanda i nije Unixicna. ;)

Ali ono, find je dovoljno mocan da moze i sam da ti zavrsi 99% stvari koje si naveo. :D

A sto se tice bezbednosti, preporucuju -execdir.


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Marel 16 Мај 2008, 21:40:29
Da li može nekako da se izvede ovako nešto:

Kod:
for file in `find . -type f`; do
    # radimo nešto sa promenjljivom $file
done

Pošto for koristi space kao separator, svi fajlovi koji sadrže ovaj znak u svom nazivu će se tretirati kao dva.

Najbolje rešenje koje sam smislio je da se napravi fajl "../skript":

Kod:
read file
while [ "$file" ]; do
    # radimo nešto sa promenjljivom $file
    read file
done

pa da se pozove sa

Kod:
find . -type f | sh ../skript



Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Časlav Ilić 16 Мај 2008, 22:17:13
Možeš to da spakuješ u zaglavlje petlje:
Kod:
find . -type f | while read file; do
    # radimo nešto sa promenjljivom "$file", al' uvek pod navodnicima
done


Naslov: Odg: BASH: kako iskopirati fajlove u svim poddirektorijumima u jedan direktoriju
Poruka od: Marel 16 Мај 2008, 23:56:09
Stvarno korisna funkcionalnost. Nije mi palo na pamet da to može (jer je while built in naredba). :)


Powered by SMF 1.1.6 | SMF © 2005, Simple Machines LLC | Srpski prevod uredio: tomaja [linuxo.org]
Joomla Bridge by JoomlaHacks.com