Як скопіювати приховані (починаючи з крапки) файли та підкаталоги в 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.