TL; DR
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
С некоторыми условиями (архивировать только файлы, директории и символические ссылки):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Объяснение
Ниже, к сожалению, есть родительский каталог ./
в архиве:
tar -czf mydir.tgz -C /my/dir .
Вы можете переместить все файлы из этого каталога с помощью параметра конфигурации --transform
, но это не избавляет от самого каталога .
. Приручить команду становится все труднее.
Вы можете использовать $(find ...)
для добавления списка файлов к команде (как в magnus 'answer ), но это может привести к ошибке «file list too long». Лучший способ - объединить его с опцией tar -T
, например:
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
По сути, он перечисляет все файлы (-type f
), ссылки (-type l
) и подкаталоги (-type d
) в вашем каталоге, делает все имена файлов относительными, используя -printf "%P\n"
, и затем передает их в tar команда (принимает имена файлов из STDIN, используя -T -
). Опция -C
необходима, чтобы tar знал, где находятся файлы с относительными именами. Флаг --no-recursion
указывает на то, что tar не попадает в папки, которые ему сообщают в архив (вызывая дублирование файлов).
Если вам нужно сделать что-то особенное с именами файлов (фильтрация, последующие символические ссылки и т. Д.), Команда find
довольно мощная, и вы можете проверить это, просто удалив часть tar
вышеуказанной команды:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
Например, если вы хотите фильтровать файлы PDF, добавьте ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
Не-GNU находка
Команда использует printf
(доступно в GNU find
), которая сообщает find
для вывода результатов с относительными путями. Однако, если у вас нет GNU find
, это делает относительные пути относительными (удаляет родителей с sed
):
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -