Відповіді:
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 -czvf my_directory.tar.gz -C my_directory .
-C my_directory
Каже дьоготь для зміни поточного каталогу 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
Вираз трансформації аналогічний експресії 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
варіантом дьогтю , як це:
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
Опція необхідна , так дьоготь знає , де файли з відносними іменами розташовані. --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 .[^.]* ..?* *
Це хитрість, яку я дізнався з цієї відповіді .
Тепер дьоготь повертає помилку , якщо є файли не відповідають ..?*
або .[^.]*
, але він все одно буде працювати. Якщо помилка є проблемою (ви перевіряєте успіх у сценарії), це працює:
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 (перший аргумент - це шлях до dir, другий аргумент - базове ім'я результуючого архіву):
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 ..
Цей працював для мене, і він включає всі приховані файли без розміщення всіх файлів у кореневій директорії з назвою "." як у відповіді tomoe :
Це те, що працює для мене.
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 ')
У першій команді знайдіть повертає список файлів і підкаталогів my_dir . Однак сам каталог my_dir включений у цей список як "." The -printf видаляє повний шлях, включаючи цей '. а також усіcrlf Однак простірв рядку формату «% Р» з PRINTF залишає залишку в списку файлів і підкаталогів my_dir і можна побачити на провідних просторі в результаті знаходять команди.
Це не буде проблемою для TAR, але якщо ви хочете виправити це, додайте -mindepth 1, як у другій команді.
Використовуйте pax.
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'
команду find або подібний фільтр для обмеження включених файлів.
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
нього додається лише файли.