Автор Тема: Две действия в един ред  (Прочетена 1568 пъти)

mrowcp

  • Напреднали
  • *****
  • Публикации: 450
    • Профил
Две действия в един ред
« -: 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

И да не се занимавам? :)
« Последна редакция: Dec 03, 2011, 15:05 от mrowcp »
Активен

Some Things Just Are The Way They Are

nov_chovek

  • Напреднали
  • *****
  • Публикации: 536
  • Distribution: Ubuntu 8.10 по принуда
  • Window Manager: Gnome
    • Профил
    • WWW
Re: Две действия в един ред
« Отговор #1 -: Dec 03, 2011, 13:05 »
защо ползваш cp при положение, че само mv прави това което искаш? mv=move
Активен

ntrance

  • Напреднали
  • *****
  • Публикации: 696
    • Профил
Re: Две действия в един ред
« Отговор #2 -: Dec 03, 2011, 13:52 »
E мерак му е ;)
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: Две действия в един ред
« Отговор #3 -: Dec 03, 2011, 13:58 »
Ако броим редове в кода ;)
Код
GeSHi (Bash):
  1. for file in *; do [ -f "$file" ] && cp "$file" dir1 && mv "$file" dir2 ; done
А иначе защо прави и cp, и mv може да прочетете в условието на "задачата" :)
Активен

mrowcp

  • Напреднали
  • *****
  • Публикации: 450
    • Профил
Re: Две действия в един ред
« Отговор #4 -: Dec 03, 2011, 15:04 »
Мерси.
Всъщност примера с "for" е идентичен на:

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

или греша?
Активен

Some Things Just Are The Way They Are

solarflux

  • Напреднали
  • *****
  • Публикации: 100
    • Профил
Re: Две действия в един ред
« Отговор #5 -: Dec 03, 2011, 15:09 »
find /usr/testdir -type f -maxdepth 1 | awk '{print "cp " $0 " dir1 && mv " $0 " dir2"}' | bash
предполагам така би станало...
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: Две действия в един ред
« Отговор #6 -: 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
« Последна редакция: Dec 05, 2011, 14:52 от bop_bop_mara »
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Re: Две действия в един ред
« Отговор #7 -: 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
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: Две действия в един ред
« Отговор #8 -: Dec 05, 2011, 15:59 »
Това за whitespaces го казах в духа на xargs, понеже видях в man-а, че, ако в аргументите има такива, става малко по-особено.

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