Як я можу переміщувати всі файли в підкаталогах рекурсивно до одного каталогу?


10

Я намагаюся зібрати всі файли в поточному каталозі та всі підкаталоги в один каталог. Я намагаюся щось подібне

find -type f -exec mv {} collection/{} \; 

вищевказана команда не буде працювати, оскільки друга {}дає повний шлях, як я можу зібрати всі файли?

Відповіді:


14

Видаліть {}з mv, mvсприйме це як цільовий каталог, ігноруючи будь-які батьківські каталоги:

find -type f -exec mv {} collection/ \;

ой, що мені не прийшло в голову. дякую :)
Кролик зайчика

Як я кажу у своїй відповіді на запитання, це потенційно погана ідея. Можливо, використання аргументу -maxdepth 1допоможе.
loevborg

Подумайте про це, схоже, я неправильно прочитав ваше запитання :) Вибачте.
loevborg

@loevborg: Я зараз додав "рекурсивно" до назви. Якщо все ще є плутанина, відредагуйте її та вдосконаліть :)
Lekensteyn

1
find -type f -print0|xargs -0r mv -it colection/
Більш

5

Замість використання find(що робить роботу добре), ви також можете використовувати оболонку для цього.

Скажіть, що ви хочете, щоб усі файли від $ PWD до $ DEST. Природною спробою було б:

mv $PWD/* $DEST

Як це працює? Вираз "$ PWD / *" розширюється на імена всіх файлів у цій директорії. Ця функція оболонки називається "глобулінг". Останній аргумент mv- це каталог призначення. Якщо у вас дуже багато файлів, це не працюватиме, оскільки довжина командного рядка обмежена.

Але у вирішенні проблеми є те, що він опускає крапкові файли - або "приховані" файли, файли та каталоги, назва яких починається з ".". Щоб вирішити це, ви повинні сказати своїй оболонці, щоб вона включала точкові файли під час глобалізації. Для цього використовуйте

shopt -s dotglob

під час використання bash(і ви, ймовірно, використовуєте, bashякщо ви не змінили типовий режим). У цій оболонці вищевказана команда також буде працювати для точкових файлів.

З іншого боку, у zshвас є можливість вибирати це в кожному конкретному випадку. Для цього поставте

setopt extendedglob

у вашому .zshrc. Тоді можна використовувати

mv $PWD/*(D) $DEST

щоб перемістити всі файли, включаючи dotfiles. ("D" впливає на тимчасове включення опції "GLOB_DOTS").

Тепер початкове питання полягав у переміщенні всіх звичайних файлів (а не каталогів) з усіх підкаталогів та їхніх підкаталогів в єдиний каталог. Це можна досягти за допомогою zsh:

mv $PWD/**/*(D.)

Тут вираз **/*змушує глобус спускатися рекурсивно в підкаталоги. В Dкошти «також вибрати точкові файли, а .значить" вибрати тільки звичайні файли, а НЕ каталоги ".


добре, я хотів також повторитись у всіх підкаталогах, але завдяки будь-якій інформації, яка корисна, зустрічайте цю ситуацію занадто багато разів :)
Кролик Бані

Власне, пошук цього не є надмірним для цього, глобус обере всі збіги, не лише файли, а й каталоги. Якщо ви турбуватися про продуктивність, ви можете також використовувати що - щось на кшталт: find -type f -exec mv -t collection/ {} +. Зверніться до сторінки керівництва про те, як це працює.
Лекенштейн

Лекенштейн, ти маєш рацію. Я оновив відповідь зараз, коли зрозумів питання.
loevborg

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