Как скопировать папки и подпапки с выбранными файлами - PullRequest
1 голос
/ 26 сентября 2019

У меня есть каталог oridir со следующей структурой:

.
├── DIRA
│   ├── DIRA1
│   │   └── file2.txt
│   └── DIRA2
│       ├── file1.xls
│       └── file1.txt
└── DIRB
    ├── DIRB1
    │   └── file1.txt
    └── DIRB2
        └── file2.xls

Я должен копировать файлы с расширением .xls, сохраняя при этом структуру каталогов.Поэтому мне нужно иметь следующий каталог и файлы в папке newdir:

.
├── DIRA
│   └── DIRA2
│       └── file1.xls
└── DIRB
    └── DIRB2
        └── file2.xls

Я попробовал следующую команду, но она скопирует все файлы и папки:

cp -r oridir newdir

Поиск необходимых файлов можетсделать это следующим образом:

$ find oridir | grep xls$
oridir/DIRB/DIRB2/file2.xls
oridir/DIRA/DIRA2/file1.xls

Также следующим образом:

$ find oridir -type f -iname *.xls
./oridir/DIRB/DIRB2/file2.xls
./oridir/DIRA/DIRA2/file1.xls

Но как создать эти папки и скопировать файлы.Как я могу добиться этого выбранного создания каталогов и копирования файлов с помощью `bash 'в Linux?

Редактировать: в некоторых именах файлов и каталогов также есть место.

Ответы [ 3 ]

1 голос
/ 26 сентября 2019

Если каталог назначения - "dest".

foo.sh

#!/bin/bash
dest=./dest
find . -type f -name "*.xls" | while read f
do
    d=$(dirname "${f}")                                                         
    d="${dest}/${d}"
    mkdir -p "${d}"
    cp "${f}" "${d}"
done

Создать каталоги и файлы.

$ mkdir -p DIRA/DIRA1
$ mkdir -p DIRA/DIRA2
$ mkdir -p DIRB/DIRB1
$ mkdir -p DIRB/DIRB2
$ touch DIRA/DIRA1/file2.txt
$ touch DIRA/DIRA2/file1.xls
$ touch DIRA/DIRA2/file1.txt
$ touch DIRB/DIRB1/file1.txt
$ touch DIRB/DIRB1/file2.xls

Результат равен

$ find dest
dest
dest/DIRB
dest/DIRB/DIRB1
dest/DIRB/DIRB1/file2.xls
dest/DIRA
dest/DIRA/DIRA2
dest/DIRA/DIRA2/file1.xls
1 голос
/ 26 сентября 2019

Сначала посмотрите отличный ответ Юджи, но я думаю, что tar также является хорошим вариантом здесь:

cd oridir; find . -name "*.xls" | xargs tar c | (cd ../newdir; tar x)

Возможно, вам придется настроить oridir и / или ../newdir в зависимости от точных путейиз ваших каталогов.

Возможное улучшение: вот версия, которая может быть лучше, так как она будет обрабатывать файлы (и пути) с пробелами (или другими странными символами) в своих именах, и использует tar 's собственные параметры вместо xargs и cd:

cd oridir; find . -print0 -name "*.xls" | tar -c --null -T- | tar -C ../newdir -x

Объяснение:

-print0 и --null приводят к тому, что соответствующие команды разделяют имена файлов на ноль (ASCII 0) только символ.

-T- заставляет tar читать имена файлов из стандартного ввода.

-C вызывает tar до cd перед извлечением.

1 голос
/ 26 сентября 2019
Флаг

cp's --parents позволяет использовать полное имя исходного файла в DIRECTORY

Например, если включен рекурсивный глоб * ** (shopt -s globstar):

cp --parents origin/**/*.xls target

Если рекурсивныйglob не включен, вы должны добавить подстановочный знак для каждого уровня в иерархии каталогов:

cp --parents origin/*/*/*.xls target
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...