Як скопіювати приховані (починаючи з крапки) файли та підкаталоги в Linux?


10

Як скопіювати приховані файли та приховані підкаталоги (ті, що починаються з крапки) у папку А до папки B? Наприклад, якщо у мене є така структура:

A/a
A/b
A/.a
A/.b/
A/.b/somefile
A/.b/.c

Я хотів би скопіювати в B тільки приховані файли та приховані підкаталоги в A:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

Я вже спробував цю команду: cp A/.* Bз цього іншого питання про суперпопулярність . Однак підкаталоги не копіюють. Також спробував cp -r A/.* B, але він копіює, .тому я закінчую точною копією A (включаючи звичайні файли). Будь-яка допомога вдячна.

Відповіді:


16

Поки ви шукаєте лише приховані файли та папки на рівні A, а не хочете, наприклад

A/b/.hidden

щоб бути скопійованим, ви повинні мати можливість використовувати це:

cp -r A/.[^.]* B

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

Редагувати: Видалено -p з команди cp, оскільки Asker не вказав, що хоче зберегти будь-які права власності, дати тощо.


Це працює для прикладів назв файлів та каталогів, наведених у запитанні, але текст запитання містить "приховані файли та приховані підкаталоги (ті, що починаються з крапки"), і ця відповідь не знайде файлів та каталогів, імена яких починаються з дві крапки; наприклад, ..c.
— Скотт

Це доволі крайній випадок, але законне занепокоєння не менше. Я не вважав цього. Ви можете пояснити це, перейшовши на, .*[^.]але тоді ви пропустите файли, які закінчуються символом a .. Я думаю, що вам справді знадобиться розширена глобалізація, щоб справді враховувати всі випадки.
— Усюдисутність

4

Проблема A/.*полягає в тому, що існує каталог, .в Aякому також відповідає шаблон.

Ви можете увімкнути розширені шаблони глобуса та скористатися такими:

shopt -s extglob
cp -r A/.!(?(.)) B    

Він відповідає файлам, ім'я яких починається з крапки, а другий символ якого - ні крапка, ні нічого (? (.) Не відповідає нічого або крапці,! (...) заперечує його, тобто! (? (.)) Відповідає всім іншим ніж нічого або крапка).


+1 для правильної відповіді. Зауважте, що .!(@(|.))(AFAICT) еквівалент вищевикладеному, (IMNSHO) трохи чіткіше і лише на один символ довший.
— Скотт

3

У таких випадках рекомендується використовувати findзамість cpцього:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

Основний синтаксис розпадається так:

  • find A/ -type f: findелементи в каталозі A/, типом яких є файл (замість каталогу)…
  • -maxdepth 1 -name '.*': Для цього maxdepthз 1 каталогів і з яких nameпочинається ..
  • -exec cp -p {} B/ \;І як тільки ці файли знайдені, команда з прапором для збереження дати / часу з джерела ( ) до пункту призначення .execcp-p{}B/

Мені подобається використовувати maxdepthшар керування, тому я випадково не копіюю всю файлову систему. Але сміливо знімайте це.


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d надає рекурсивний список в межах A, який містить лише каталоги
  • grep -E "\." фільтрує каталоги з крапкою (тобто: приховані каталоги)
  • Тут потрібна була опція -E, оскільки без неї це означає "поточний каталог"
  • зворотна косої риси полягає в тому, щоб уникнути значення "будь-якого персонажа"
  • cp -r копіювати рекурсивно

Я створив структуру файлів і папок для A і виконав команду в Git Bash (я зараз не з linux), і це спрацювало.


Це порушується, якщо у файлах є пробіли або спеціальні символи у своєму імені чи шляху.
— slhck

Дякую, що помітили :) Насправді я обмежився "тестовим випадком" від @gaboroncancio. Якщо ви можете дати мені інший тестовий акумулятор, я, можливо, спробую вдосконалити це (звичайно, якщо хочете, вдосконаліть його самостійно, відредагувавши цю відповідь або створивши нову відповідь)
— malarres

Ви можете просто помістити точкові файли у папку під назвою A B, а потім вона діятиме несподівано, оскільки вона розшириться на cp -r A B/.dotfile B. Загальна порада взагалі не розбирати findчи lsвиводити . Якщо ви використовуєте, findви також повинні використовувати його власні параметри для фільтрації, а не grep, і якщо ви передаєте findвисновок десь в іншому місці, використовуйте -print0або безпосередньо зателефонуйте потрібній команді. Дивіться find посібник .
— slhck

Навіть загальніше, при роботі з файлами найбезпечніше використовувати кулі оболонки, як пояснено в інших відповідях (хоча вони часто вимагають extglobвстановити).
— slhck

Дякуємо за посилання Залишимо findрозбір тоді.
— malarres

0

В якості альтернативи ви можете використовувати цю іншу команду, якщо другий символ буквено-цифровий ( джерело ):

cp -r A/.[a-zA-Z0-9]* B

Це працює для прикладів назв файлів та каталогів, наведених у запитанні, але текст запитання містить "приховані файли та приховані підкаталоги (ті, що починаються з крапки"), і ця відповідь не знайде файлів та каталогів, імена яких починаються з крапка і особливий символ; наприклад, .@fooабо ..c.
— Скотт

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