Скопіюйте всі файли з певним розширенням з усіх підкаталогів


112

Під unix я хочу скопіювати всі файли з певним розширенням (усі файли excel) з усіх підкаталогів в інший каталог. У мене є така команда:

cp --parents `find -name \*.xls*` /target_directory/

Проблеми з цією командою:

  • Він також копіює структуру каталогів, і я хочу лише файли (тому всі файли повинні знаходитися в / target_directory /)

  • Він не копіює файли з пробілами у назви файлів (яких досить багато)

Будь-які рішення цих проблем?



Відповіді:


174

--parents копіює структуру каталогів, тому слід позбутися цього.

Те, як ви це написали, findвиконує і виводить на командний рядок таким чином, що cpне можна розрізнити пробіли, що розділяють назви файлів, та пробіли у назви файлу. Краще зробити щось на кшталт

$ find . -name \*.xls -exec cp {} newDir \;

в якому cpвиконується кожне ім'я файлу, яке findзнайде, і передало ім'я файлу правильно. Ось більше інформації про цю техніку.

Замість усього вищесказаного можна використовувати zsh та просто набрати

$ cp **/*.xls target_directory

zsh можна розширити підстановки, щоб включити підкаталоги, і дуже полегшує подібні речі.


2
Так. "бін" означає викинути його. Тепер внесені зміни :-)
Брайан Агнеу

13
Bash4.0+, а ksh93також підтримує **. Для bash використовуйте shopt -s globstarдля його включення. Для ksh, це set -Gабо set -o globstar.
pynexj

2
@Daryl - я заповнив далі. Але відповідь уже було позначено як "прийнято", зауважте
Брайан Агнеу

5
Цей exec технічно менш ефективний, ніж перехід на xargs, що зробить це за find . -name '*.xls' -print0 | xargs -0 cp -t destdir
найменший

2
@BrianAgnew О, я впевнений, просто добре мати додаткову інформацію у коментарях для зухвалих гуглерів.
Taywee

37

З усього вищесказаного я придумав цю версію. Ця версія також працює для мене в терміналі відновлення mac.

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'

Він буде шукати у поточному каталозі та рекурсивно у всіх підкаталогах для файлів із розширенням xsl. Це скопіює їх усіх у цільовий каталог.

CPP прапорами є:

  • p - збереження атрибутів файлу
  • r - рекурсивний
  • v - багатослівний (показує, що копіюється)

1
Це те саме, що я мав робити, коли SSH зайшов у Bluehost.
Плюмер

4
Він НЕ зберігає підкаталоги.
b005t3r

3
@ b005t3r, що за дизайном, не передбачається. В цьому і полягала вся ціль питання ОП. Він хотів, щоб усі файли з підкаталогів скопіювали в один каталог без підкаталогів
Мадівад,

2
Чи є спосіб змінити це для збереження підкаталогів?
Метью Дін

8

У мене була схожа проблема. Я вирішив це за допомогою:

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"

'{}'І ";"виконує копію на кожен файл.


3

Я також повинен був зробити це сам. Я зробив це через аргумент --parents для cp:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;

1
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

Ви можете видалити --parents, але є ризик зіткнення, якщо кілька файлів мають одне ім’я.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.