Исключите определенные каталоги из ls и скопируйте оставшиеся в общий путь.

У меня есть папка, содержащая подкаталоги A,B,C and D. Мне нужно скопировать каталоги A and D в другой каталог с именем 'copy', исключая B and C (т.е. B и C не копируются). Я думал о том, чтобы сделать следующее (в псевдокоде командной строки):

ls (selective ls on the source directory) | 
   scp -r {returned value from the ls} {target directory}

Есть ли способ командной строки Linux для выполнения вышеуказанного?


person sc_ray    schedule 04.06.2012    source источник


Ответы (3)


Простой ответ — копировать только те каталоги, которые вы хотите:

scp -r A D anotherhost:/path/to/target/directory

Это будет делать именно то, что вы описали в своем примере. Более общее решение может выглядеть примерно так:

scp -r $(ls | egrep -v '^(B|C)$') anotherhost:/path/to/target/directory

Эта команда будет работать до тех пор, пока количество файлов в исходном каталоге невелико. По мере увеличения количества файлов вы в конечном итоге столкнетесь с ошибкой «команда слишком длинная».

Вместо использования scp вы можете использовать rsync, который имеет множество механизмов для включения/исключения файлов. Например:

rsync --exclude='B/' --exclude='C/' . anotherhost:/path/to/target/directory
person larsks    schedule 04.06.2012

Я бы предложил использовать find для этого.

Давайте создадим несколько испытуемых:

$ mkdir -p ./testing/test{1,2,3,4}
$ touch ./testing/test{1,2,3,4}/test{a,b}

Приведет к:

$ ls -R ./testing
./testing:
test1  test2  test3  test4

./testing/test1:
testa  testb

./testing/test2:
testa  testb

./testing/test3:
testa  testb

./testing/test4:
testa  testb

Теперь беги

$ mkdir ./testing/copy
$ find ./testing/ -mindepth 1 -maxdepth 1 ! -name test1 ! -name test3 ! -name copy -execdir cp -R '{}' ./copy/ ';'

Приведет к:

$ ls -R ./testing/
./testing/:
copy  test1  test2  test3  test4

./testing/copy:
test2  test4

./testing/copy/test2:
testa  testb

./testing/copy/test4:
testa  testb

./testing/test1:
testa  testb

./testing/test2:
testa  testb

./testing/test3:
testa  testb

./testing/test4:
testa  testb

Исходная информация:

Сводка: найдите каталоги, которые необходимо скопировать, и выполните команду копирования. В этом случае давайте скопируем все каталоги, кроме «test1» и «test3».

Опция -mindepth 1 предотвратит включение в find файла . и, возможно, .. каталоги, так как они находятся на глубине 0.

Параметр -maxdepth 1 предотвратит копирование каждого отдельного подкаталога в find. Команда cp -R обрабатывает подкаталоги, поэтому они закрыты.

Используйте -execdir вместо -exec, чтобы не указывать весь путь в качестве целевого каталога для команды cp.

НЕ ЗАБЫВАЙТЕ сделать mkdir целевой директории перед запуском поиска и НЕ ЗАБЫВАЙТЕ исключать эту директорию из результатов! Отсюда ! -name copy в моем примере.

Я надеюсь, что это указывает вам в правильном направлении.

person Christian Stadegaart    schedule 04.06.2012

Если вы действительно знаете свои каталоги, просто добавьте все в scp:

scp A/* D/* targetHost:/copy

Единственная проблема с этим решением заключается в том, что оно «смешивает» ваши файлы в каталоге копирования. Наверное, это неважно :-)

person Bogatyr    schedule 04.06.2012