Ответы:
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
должен делать работу в одну строку. Это хорошо работает и для скрытых файлов. «*» не раскрывает скрытые файлы путем расширения имени пути, по крайней мере, в bash. Ниже мой эксперимент:
$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
.
на *
так, команда будет, cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..
тогда она будет работать, как вы ожидали.
$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
cd
входить в каталоги и выходить довольно неубедительно. Мог бы по крайней мере использовать, pushd
и popd
если tar
не было никаких флагов, как -C
.
Используйте -C
переключатель tar:
tar -czvf my_directory.tar.gz -C my_directory .
Команда -C my_directory
tar сообщает об изменении текущего каталога my_directory
, а затем .
означает «добавить весь текущий каталог» (включая скрытые файлы и подкаталоги).
Убедитесь, что вы делаете, -C my_directory
прежде чем вы делаете, .
иначе вы получите файлы в текущем каталоге.
tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a
« apl.jhu.edu/Misc/Unix-info/tar/tar_65.html Я всегда стараюсь tar -czvf my_directory.tar.gz * -C my_directory
и это не работает. -C
местоположение важно! Черт возьми ...
*
не будет включать скрытые файлы (что было первоначальным требованием).
Вы также можете создать архив как обычно и распаковать его:
tar --strip-components 1 -xvf my_directory.tar.gz
--strip-components
это расширение GNU.
Посмотрите на --transform
/ --xform
, это дает вам возможность поменять имя файла при добавлении файла в архив:
% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz
file2
.hiddenfile1
.hiddenfile2
file1
Выражение преобразования аналогично выражению of sed
, и мы можем использовать разделители, отличные от /
( ,
в приведенном выше примере).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
file list too long
. Мое решение предотвращает это и является более гибким.
--xform
несколько раз для нескольких путей.
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 ...)
для добавления списка файлов в команду (как в ответе Магнуса ), но это может привести к ошибке «список файлов слишком длинный». Лучший способ - объединить его с -T
опцией tar , например так:
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
), links ( -type l
) и подкаталогов ( -type d
) в вашем каталоге, устанавливает относительное использование всех имен файлов -printf "%P\n"
, а затем передает их команде tar (она берет имена из STDIN с использованием -T -
). -C
Опция необходима , так деготь знает , где файлы с относительными именами расположены. --no-recursion
Флаг так , чтобы смола не рекурсии в папки Рассказываются в архив (порождение дубликатов файлов).
Если вам нужно сделать что-то особенное с именами файлов (фильтрация, следующие символические ссылки и т. Д.), 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
Команда использует 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 -
Этот ответ должен работать в большинстве ситуаций. Обратите внимание, однако, как имена файлов хранятся в файле tar как, например, ./file1
а не просто file1
. Я обнаружил, что это вызывает проблемы при использовании этого метода для манипулирования тарболами, используемыми в качестве файлов пакетов в BuildRoot .
Одним из решений является использование некоторых глобусов Bash для вывода списка всех файлов, кроме ..
следующих:
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
Это трюк, который я узнал из этого ответа .
Теперь tar вернет ошибку, если не найдено ни одного файла, соответствующего ..?*
или .[^.]*
, но он все равно будет работать. Если ошибка является проблемой (вы проверяете успех в сценарии), это работает:
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
Хотя сейчас мы работаем с параметрами оболочки, мы можем решить, что лучше иметь *
совпадающие скрытые файлы:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
Это может не сработать, если ваша оболочка перемещается *
в текущем каталоге, поэтому в качестве альтернативы используйте:
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
tar: start.sh: Cannot stat: No such file or directory
Это происходит со всеми файлами в моем текущем каталоге! Как мне избежать этого?
Я бы предложил следующую функцию Bash (первый аргумент - путь к каталогу, второй аргумент - базовое имя результирующего архива):
function tar_dir_contents ()
{
local DIRPATH="$1"
local TARARCH="$2.tar.gz"
local ORGIFS="$IFS"
IFS=$'\n'
tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
IFS="$ORGIFS"
}
Вы можете запустить его таким образом:
$ tar_dir_contents /path/to/some/dir my_archive
и он сгенерирует архив my_archive.tar.gz
в текущем каталоге. Он работает со скрытыми (. *) Элементами и с элементами с пробелами в имени файла.
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
Этот работал для меня, и он включает все скрытые файлы, не помещая все файлы в корневой каталог с именем "." как в ответе Томоэ :
Это то, что работает для меня.
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
Вы также можете использовать
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
В первой команде find возвращает список файлов и подкаталогов my_dir . Однако каталог my_dir сам по себе включен в этот список как «.» -printf удаляет полный путь, включая этот «.» а также всеCRLF Однако пространствов строке формата «% Р» из PRINTF оставляет остатка в списке файлов и подкаталогов my_dir и можно увидеть на ведущих пространстве в результате находят команды.
Это не будет проблемой для TAR, но если вы хотите это исправить, добавьте -mindepth 1, как во второй команде.
Пакс.
Pax - устаревший пакет, но делает работу отлично и просто.
pax -w > mydir.tar mydir
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
{ cd "$1" && find -type f -print0; } \
| cut --zero-terminated --characters=3- \
| tar --create --file="$2" --directory="$1" --null --files-from=-
}
Безопасно обрабатывает имена файлов с пробелами или другими необычными символами. При желании вы можете добавить -name '*.sql'
или подобный фильтр к команде поиска, чтобы ограничить количество включаемых файлов.
tar -cvzf tarlearn.tar.gz --remove-files mytemp/*
Если папка mytemp, то, если вы примените вышеизложенное, она заархивирует и удалит все файлы в папке, но оставит ее в покое.
tar -cvzf tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
Вы можете задать шаблоны исключений, а также указать, что не следует просматривать вложенные папки.
tar -czf
? В моем случае это только хранение файлов, а не каталог. Когда я простоtar
каталог, он включает его, но сtar -czf
ним только добавление файлов.