Рекурсивное копирование скрытых файлов - Linux


19

Есть ли простой способ рекурсивного копирования всех скрытых файлов в каталоге в другой каталог? Я хотел бы сделать резервную копию только всех файлов настроек в домашнем каталоге, а не обычных файлов. Я старался:

cp -R .* directory

но он распознает .и ..и рекурсивно копирует все не скрытые файлы тоже. Есть ли способ заставить cp игнорировать .и ..?


Есть ли разница между -rи -R?
Чаминда Бандара

Ответы:


15

Моим любимым ходом режиссеров вообще было:

tar cvf - . | (cd /dest/dir; tar xvf -)

который подключает текущий каталог к ​​стандартному выводу, а затем направляет его в подоболочку, которая сначала переписывает компакт-диск в конечный каталог перед тем, как распаковать стандартный ввод. Простой, прямой, расширяемый - подумайте, что происходит, когда вы заменяете () ssh на другой компьютер. Или, чтобы ответить на ваш вопрос, вы можете сделать:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)

1
Спасибо, опция исключения - это то, что мне нужно. Я уже сделал это по-другому, но я оставлю это для дальнейшего использования. Это кажется действительно гибким (хотя, может быть, медленнее).
Zifre

1
Хороший совет. У меня есть пара улучшений: 1) Использование cd /dest/dir && tar xvf -. &&Остановит вас от blatting по каталогу источника , если у вас есть опечатка в пункте назначения. 2) Вам нужен только vфлаг tar для одной из команд tar (или ни одной).
Том Шоу

Справедливо. Мне также известно, что можно группировать вещи другим способом: скопировать сюда удаленный srcdir, сделайте(cd /src/dir && tar cf - .) | tar xvf -
pjz

17

Почти каждый раз, когда это можно решить просто с помощью:

cp -R .[a-zA-Z0-9]* directory

Довольно необычно иметь скрытый файл, который не начинается с одного из этих символов.

Другие сопоставления с образцами доступны ( .??*, .[^.]*) - см. Комментарии


Это будет игнорировать только.-Xyz - материал в [] соответствует только первому символу после точки.
Хэмиш Даунер

6
. [^.] * поймал бы все
фальстро

1
... кроме вещей, начинающихся с двух периодов.
Falstro

@roe - это тоже хорошая версия
Alnitak

@mish - да, я сказал так же в ответе.
Альнитак,

11

Вы могли бы использовать rsync.

rsync -a ./ /some/other/directory/

который скопирует содержимое текущего каталога (включая точечные файлы, но не включая ..)


Простой и работает для скрытых файлов в скрытых папках тоже.
user59183

для меня это менее запутанный и самый эффективный из предоставленных решений
palerdot

Хорошее решение. Я также нуждался в этом, чтобы не копировать через .gitкаталоги. Добавление -C делает это, и поэтому команда становится:rsync -aC ./ /some/other/directory/
Theruss

10

Я умоляю вас, шаг от простого расширения оболочки в cpкомандной строке - оболочка расширение имеет все виды гм . «Интересных» угловые случаи (нежелательных рекурсию , вызванные и .., пробела, непечатаемые вещи, жесткие ссылки, символические ссылки, и и т. д.) Используйте findвместо этого (он входит в findutilsпакет, если он у вас не установлен - что было бы странно, все дистрибутивы устанавливают его по умолчанию):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Пошаговое объяснение:

  • -Hприведет к тому, что findне будет следовать символическим ссылкам (кроме случаев, когда фактическое имя каталога верхнего уровня, которое вы дали, является символической ссылкой; это будет следовать.)
  • /path/to/toplevel/dir/ Очевидно, что он должен быть заменен вами путем к каталогу, в котором находятся файлы настроек и каталоги, резервные копии которых вы хотите создать.
  • -maxdepth 1остановит findрекурсивный спуск в любые каталоги, имя которых начинается с точки. Нам не нужно это повторять, cpмы сделаем это за нас, нам просто нужны имена на этом уровне.
  • -name '.*'говорит, findчто мы хотим, чтобы все имена начинались с точки. Это не будет работать правильно, если установлена ​​переменная окружения POSIXLY_CORRECT, но редко (если вообще когда-либо). Это первое условие соответствия, которое мы указали до сих пор.
  • a \( ....... \)является и сопровождается более сложным условием в скобках (я использовал ..... для его замены, это объяснено ниже.) Нам нужно избегать скобок, так как иначе они будут (неправильно) интерпретироваться оболочкой, отсюда и обратный слеш перед ними,
  • -type d -o -type f -o -type lтри условия с или между ними. -type dсопоставляет каталоги, -type fсопоставляет обычные файлы и -type lсопоставляет символические ссылки. Вы можете выбрать то, что вы хотите - например, если вы не хотите делать резервные копии каталогов настроек, опустите -type d( -oочевидно, и справа за ним).
  • -exec ..... \;говорит findвыполнить команду каждый раз, когда встречается совпадение. Конец команды отмечен точкой с запятой, которую мы снова должны экранировать обратной косой чертой, чтобы избежать интерпретации оболочки. В этой командной строке вам нужно использовать, {}где вы хотите, чтобы имя встречающегося в данный момент совпадения заканчивалось. Так как оболочки могут также неверно истолковывать фигурные скобки, вы должны поместить их в апострофы, как в '{}'. В этом случае мы хотим выполнить команду cp -a '{}' /path/to/destination/dir/(-a означает архив, который повторяется в подкаталогах, копирует символические ссылки в виде ссылок и сохраняет разрешения и расширенные атрибуты и /path/to/destination/dir/, очевидно, является именем целевого каталога - замените его.)

Итак, на простом английском языке эта findкомандная строка говорит следующее:

Начните с / path / to / toplevel / dir /. Не спускайтесь ни в какие подкаталоги. Найти все каталоги, файлы и символические ссылки, чье имя начинается с точки. Для каждого из найденных объектов скопируйте его в / path / to / destination / dir / сохраняя природу, разрешения и расширенные атрибуты.


1
найти это самая полезная вещь когда-либо.
Мистер Блестящий и Новый

1
Хороший ответ. Хотя я предпочитаю -exec ... ';' Избегание обратной косой черты означает, что эта команда будет работать как в CLI, так и в crontab :))
kubanczyk

8

Я всегда использовал. ?? *, чтобы найти скрытые файлы, не получая "." и "..". Это может пропустить ".a" или что-то, хотя, но у меня никогда не было одного из них.


определенно хороший и опрятный :) +1
фальстро

Я не хочу, чтобы он таинственным образом потерпел неудачу, если есть какие-то ".a"
Zifre

Мне это нравится, потому что, если вы знаете, что у вас нет скрытых файлов, состоящих из одного символа, это очень быстро набрать.
Пол Томблин

Это должен быть лучший ответ. Это должно быть поддержано наверх.
Ибн Саид

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.