Я хочу сделать резервную копию всех 'точечных файлов' (например, .zshrc
) в моем домашнем каталоге с помощью tar , но исключая структуру каталогов и все подкаталоги.
Я пробовал это несколько раз с разными командами, но лучшее, чего я достиг, - это архив, в который также были включены скрытые каталоги $HOME
.
#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*
Я также думал об использовании find
и передаче результата в tar, но безуспешно. Кто-нибудь знает, как решить эту, казалось бы, легкую задачу?
PS: Большую часть времени, когда я использую tar для создания архива, мне приходится думать о комиксе xkcd:
:)
*(.)
и я думаю, что он исключает.
и..
из.*
по умолчанию (и они не будут выбраны в.*(.)
любом случае, так как он выбирает только файлы). Я сам не пользуюсь zsh, поэтому я не уверен, чтобы превратить это в ответ.Ответы:
Вы можете использовать эту команду для резервного копирования всех ваших dotfiles (
.<something>
) в вашем$HOME
каталоге:регулярное выражение, используя только tar?
метод № 1
Я исследовал это совсем немного и пришел пустой. Ограничивающим фактором будет то, что при
tar
выполнении исключений завершающий слеш (/
), который отображается с каталогами, не является частью уравнения, когда tar выполняет сопоставление с образцом.Вот пример:
Этот вариант включает в себя исключение,
.*/
и вы можете видеть с включенным в tar подробным переключателем-v
, что эти каталоги проходят через это исключение.метод № 2
Я подумал, что, может быть, переключатели
--no-wildcards-match-slash
или--wildcards-match-slash
ослабит жадность,.*/
но это тоже не имело никакого эффекта.Удаление косой черты из исключения также
.*
не было возможным, поскольку этоtar
указывало бы на исключение всех файлов точек и каталогов точек:Метод № 3 (Гадкий!)
Поэтому единственная альтернатива, которую я могу придумать, - предоставить список файлов
tar
. Что-то вроде этого:Этот подход имеет проблемы, если число файлов превышает максимальный объем пространства для передачи аргументов в команду, было бы одной явной проблемой. Другое дело, что это безобразно и слишком сложно.
так что мы узнали?
Кажется, нет простого и элегантного способа добиться этого, используя
tar
& регулярные выражения. Что касается комментария @ terdon,find ... | tar ...
это действительно более подходящий способ сделать это.источник
regex
, но я должен был знать, что так не получится :)regex
вам, вероятно, потребуется экранировать ведущую точку, и вам будет трудно игнорировать.
и..
. Я уверен, что это возможно, так как slm, вероятно, продемонстрирует, но я не понимаю, почему это будет стоить.find
находит команда, передается в качестве аргументаtar
. The{}
говорит, где вы хотите, чтобы эти результаты были в соответствующей-exec
команде. Команда+
говорит добавить столько результатов,find
сколько поместится в командной строке, и вызыватьtar
только пару раз, а не каждый раз, когда найден результат.regex
иtar
потому что нет способа изолировать точечные каталоги (.blah/
). Tar не использует завершающий слеш при исключении.Этот вид контроля над соответствующими файлами находится вне зоны комфорта tar. Его правила сопоставления файлов ограничены простыми совпадениями по именам.
find
Это один из способов, но поскольку у вас есть Zsh, вам будет проще:То, что
.
в скобках в конце подстановочного выражения есть глобальный квалификатор, который говорит «только сопоставлять обычные файлы».Символьные ссылки на обычные файлы не совпадают. Если вы измените на
.*(-.)
, они будут включены, но файл не попадет в архив, если он также не включен. Если вы хотите заменить символическую ссылку на их цели, сделайте это.*(-.:A)
-:A
добавляет модификатор расширения истории, который разрешает все символические ссылки в пути, который не использует символические ссылки.источник
Этот ответ основан на slm, но я также покажу вам, как включать каталоги, начинающиеся с
.
Чтобы сжать точечные файлы в вашем домашнем каталоге:
Чтобы включить каталоги:
Опция
?
необязательна в первой команде, но не во второй, иначеfind
будет включать.
(текущий) каталог.источник
как насчет:
источник