Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: mrowcp в Dec 03, 2011, 12:33



Титла: Две действия в един ред
Публикувано от: mrowcp в Dec 03, 2011, 12:33
Здравейте,
Имам следните неща в директорията:

#ls
file1 file2 file3 dir1 dir2

и искам: file1, file2 и file3 да се копират едновременно в dir1 и dir2, като в същото време да бъдат изтрити от основната директория.
За целта опитах с:

Код
GeSHi (Bash):
  1. find /usr/testdir -type f -maxdepth 1 -exec cp {} /usr/testdir/dir1 \; | xargs mv {} /usr/testdir/dir2

, но нещо xargs-а определено ми куца.
Иначе го бях направил с два find-a, като единия копира, а втория мести файловете.Проблема е, че ако са по-големи, пърия find може да копира 3 файла, а 2рия да премести 4, защото през това време ще се е появил още един нов файл.

Или да направя един:

Код
GeSHi (Bash):
  1. for files in *;do
  2. cp $files /usr/testdir/dir1
  3. mv $files /usr/testdir/dir2
  4. done

И да не се занимавам? :)


Титла: Re: Две действия в един ред
Публикувано от: nov_chovek в Dec 03, 2011, 13:05
защо ползваш cp при положение, че само mv прави това което искаш? mv=move


Титла: Re: Две действия в един ред
Публикувано от: ntrance в Dec 03, 2011, 13:52
E мерак му е ;)


Титла: Re: Две действия в един ред
Публикувано от: bop_bop_mara в Dec 03, 2011, 13:58
Ако броим редове в кода ;)
Код
GeSHi (Bash):
  1. for file in *; do [ -f "$file" ] && cp "$file" dir1 && mv "$file" dir2 ; done
А иначе защо прави и cp, и mv може да прочетете в условието на "задачата" :)


Титла: Re: Две действия в един ред
Публикувано от: mrowcp в Dec 03, 2011, 15:04
Мерси.
Всъщност примера с "for" е идентичен на:

echo dir1 dir2 | xargs -n 1 cp file* && rm file*

или греша?


Титла: Re: Две действия в един ред
Публикувано от: solarflux в Dec 03, 2011, 15:09
find /usr/testdir -type f -maxdepth 1 | awk '{print "cp " $0 " dir1 && mv " $0 " dir2"}' | bash
предполагам така би станало...


Титла: Re: Две действия в един ред
Публикувано от: bop_bop_mara в Dec 05, 2011, 14:47
Мерси.
Всъщност примера с "for" е идентичен на:

echo dir1 dir2 | xargs -n 1 cp file* && rm file*

или греша?
Аз също не съм веща в xargs, но според пробата трябва да е така (в смисъл, като краен резултат, иначе има разлика в действията). В твоя случай, обаче, имаш голямо улеснение, ако наистина файловете ти се казват fileX (т.е. могат да се опишат с прост filename expansion и не съдържат whitespace в имената си). И, ако е толкова проста ситуацията, май няма смисъл нещо повече от:
Код
GeSHi (Bash):
  1. cp file* dir1 && mv file* dir2


Титла: Re: Две действия в един ред
Публикувано от: radoulov в Dec 05, 2011, 15:24
[...]
В твоя случай, обаче, имаш голямо улеснение, ако наистина файловете ти се казват fileX (т.е. могат да се опишат с прост filename expansion и не съдържат whitespace в имената си). И, ако е толкова проста ситуацията, май няма смисъл нещо повече от:
Код
GeSHi (Bash):
  1. cp file* dir1 && mv file* dir2

Решението на bop_bop_mara ми се струва най-удачно
(дори и имената на файловете да съдържат white spaces или други
shell special characters, след filename generation (globbing) не се
извършва shell word/field splitting, така че няма да има проблеми):

Код:
zsh-4.3.13[t]% touch file\ {1..2}; mkdir dir\ {1..2}
zsh-4.3.13[t]% ls -l
total 0
drwxr-xr-x+ 1 sysadmin None 0 Dec  5 14:12 dir 1
drwxr-xr-x+ 1 sysadmin None 0 Dec  5 14:12 dir 2
-rw-r--r--  1 sysadmin None 0 Dec  5 14:12 file 1
-rw-r--r--  1 sysadmin None 0 Dec  5 14:12 file 2
zsh-4.3.13[t]% cp file* dir\ 1 && mv file* dir\ 2
zsh-4.3.13[t]% ls -lR
.:
total 0
drwxr-xr-x+ 1 sysadmin None 0 Dec  5 14:13 dir 1
drwxr-xr-x+ 1 sysadmin None 0 Dec  5 14:13 dir 2

./dir 1:
total 0
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:13 file 1
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:13 file 2

./dir 2:
total 0
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:12 file 1
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:12 file 2

Бих добавил само --, за да избегна евентуални проблеми
с имена започващи с -:

Код:
zsh-4.3.13[t]% touch -- -file3
zsh-4.3.13[t]% cp *file* dir\ 1 && mv *file* dir\ 2
cp: unknown option -- e
Try `cp --help' for more information.

Така би било OK:

Код:
zsh-4.3.13[t]% cp -- *file* dir\ 1 && mv -- *file* dir\ 2
zsh-4.3.13[t]% ls -l dir\ [12]/-*
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:21 dir 1/-file3
-rw-r--r-- 1 sysadmin None 0 Dec  5 14:20 dir 2/-file3


Титла: Re: Две действия в един ред
Публикувано от: bop_bop_mara в Dec 05, 2011, 15:59
Това за whitespaces го казах в духа на xargs, понеже видях в man-а, че, ако в аргументите има такива, става малко по-особено.

Но да, в крайна сметка решението ще зависи от целта - дали се търси по-обобщен подход, или е само за една константна (и много изчистена) ситуация.